279 lines
7.3 KiB
Plaintext
Executable File
279 lines
7.3 KiB
Plaintext
Executable File
------------------------------------------------------------------------------
|
|
--
|
|
-- xml2.ms
|
|
-- MaxScript XML Reader/Writer
|
|
--
|
|
-- David Muir <david.muir@rockstarnorth.com>
|
|
-- Edit: Luke Openshaw
|
|
--
|
|
-- Uses .Net 2.0 framework (installed with Max)
|
|
--
|
|
------------------------------------------------------------------------------
|
|
|
|
------------------------------------------------------------------------------
|
|
-- Globals
|
|
------------------------------------------------------------------------------
|
|
|
|
dotnet.LoadAssembly "System.Xml.dll"
|
|
|
|
------------------------------------------------------------------------------
|
|
-- Structure Definitions
|
|
------------------------------------------------------------------------------
|
|
|
|
struct XmlElement
|
|
(
|
|
tagName = "",
|
|
children = #(),
|
|
attrs = dotnetobject "RSG.MaxUtils.MaxDictionary",
|
|
textValue = "",
|
|
|
|
fn findChild withName:undefined withAttribute:undefined =
|
|
(
|
|
if undefined!=withName then
|
|
for c in children where (c.tagname==withName) do return c
|
|
if undefined!=withAttribute then
|
|
for c in children where (c.attrs.ContainsKey withAttribute) do return c
|
|
return undefined
|
|
)
|
|
)
|
|
|
|
struct XmlDocument
|
|
(
|
|
|
|
------------------------------------------------------------------------------------
|
|
-- PUBLIC MEMBER DATA
|
|
------------------------------------------------------------------------------------
|
|
|
|
--
|
|
-- .Net System.Xml.XmlDocument Object
|
|
--
|
|
-- See http://msdn2.microsoft.com/en-us/library/system.xml.xmldocument.aspx for
|
|
-- documentation on methods and properties for node manipulation.
|
|
--
|
|
|
|
document,
|
|
maxXmlObject,
|
|
|
|
------------------------------------------------------------------------------------
|
|
-- CONSTANTS
|
|
------------------------------------------------------------------------------------
|
|
|
|
XmlNodeType = dotNetClass "System.Xml.XmlNodeType",
|
|
|
|
------------------------------------------------------------------------------------
|
|
-- PUBLIC METHODS
|
|
------------------------------------------------------------------------------------
|
|
|
|
-- FHT: I removed the garbage collection, because it was causing huge overheads on multiple small xml exports (textures)
|
|
fn Release =
|
|
(
|
|
if undefined!=document then
|
|
(
|
|
document = undefined
|
|
)
|
|
),
|
|
|
|
-- call this before you start any I/O operations
|
|
fn init force:false =
|
|
(
|
|
Release()
|
|
document = dotNetObject "System.Xml.XmlDocument"
|
|
|
|
local cpi = document.createProcessingInstruction ("xml") ("version=\"1.0\" encoding = \"UTF-8\"")
|
|
document.AppendChild cpi
|
|
),
|
|
|
|
-- save the in-memory xml document to file
|
|
fn save xmlDocName =
|
|
(
|
|
try(
|
|
if( RsFileExists xmlDocName ) then (setFileAttribute xmlDocName #readOnly false)
|
|
document.save xmlDocName
|
|
Release()
|
|
true
|
|
)catch(
|
|
msg = "Problem saving XmlDocument: \"" + xmlDocName + "\" Exception: " + getCurrentException();
|
|
gRsUlog.LogError msg context:xmlDocName
|
|
Release()
|
|
false
|
|
)
|
|
),
|
|
|
|
-- create an xmlnode
|
|
fn createnode type nodename namespace =
|
|
(
|
|
if matchPattern nodename pattern:"* *" then
|
|
(
|
|
gRsUlog.LogError ("Trying to create an xml element with spaces in its name: \""+nodename as string+"\"")
|
|
nodename = substituteString nodename " " "_"
|
|
)
|
|
|
|
xmlnode = document.createnode type nodename namespace
|
|
xmlnode
|
|
),
|
|
|
|
fn createTextNode thetext =
|
|
(
|
|
xmlnode = document.createTextNode (thetext as string)
|
|
xmlnode
|
|
),
|
|
|
|
-- create an xmlattribute
|
|
fn createattribute attrname attributeValue:undefined =
|
|
(
|
|
if matchPattern attrname pattern:"* *" then
|
|
(
|
|
gRsUlog.LogError ("Trying to create an xml element with spaces in its name: \""+attrname as string+"\"")
|
|
attrname = substituteString attrname " " "_"
|
|
)
|
|
xmlattr = document.createattribute attrname
|
|
if undefined!=attributeValue then
|
|
xmlattr.value = attributeValue as string
|
|
xmlattr
|
|
),
|
|
|
|
-- create an xmlelement
|
|
fn createelement elemname appendTo:undefined attrs:undefined value:undefined =
|
|
(
|
|
if matchPattern elemname pattern:"* *" then
|
|
(
|
|
gRsUlog.LogError ("Trying to create an xml element with spaces in its name: \""+elemname as string+"\"")
|
|
elemname = substituteString elemname " " "_"
|
|
)
|
|
xmlelem = document.createelement elemname
|
|
if undefined!=appendTo then
|
|
appendTo.appendChild xmlelem
|
|
if undefined!=attrs then
|
|
(
|
|
for pair in attrs do
|
|
(
|
|
xmlelem.SetAttribute pair[1] (pair[2] as string)
|
|
)
|
|
)
|
|
if undefined!=value then
|
|
(
|
|
local txtNode = createTextNode value
|
|
xmlelem.appendChild txtNode
|
|
)
|
|
return xmlelem
|
|
),
|
|
|
|
-- create an xmlcomment
|
|
fn createcomment thetext =
|
|
(
|
|
xmlcomment = document.createcomment thetext
|
|
xmlcomment
|
|
),
|
|
|
|
-- remove a node
|
|
fn removechild root node =
|
|
(
|
|
root.removechild node
|
|
),
|
|
|
|
fn ParseElementRec elem =
|
|
(
|
|
local theType = elem.GetType()
|
|
local elemClass = theType.name
|
|
local maxElem = undefined
|
|
if elemClass=="XmlDocument" then
|
|
(
|
|
maxElem = XmlElement()
|
|
maxElem.tagName = elem.name
|
|
)
|
|
else if elemClass=="XmlElement" then
|
|
(
|
|
maxElem = XmlElement()
|
|
maxElem.tagName = elem.name
|
|
maxElem.textValue = elem.innerText
|
|
for ai=0 to (elem.Attributes.Count-1) do
|
|
(
|
|
local attrnode = elem.Attributes.itemof ai
|
|
maxElem.attrs.add attrnode.name attrnode.value
|
|
)
|
|
)
|
|
|
|
for i=0 to (elem.ChildNodes.Count-1) do
|
|
(
|
|
local child = ParseElementRec (elem.ChildNodes.itemof i)
|
|
if undefined!=maxElem then
|
|
(
|
|
append maxElem.children child
|
|
)
|
|
)
|
|
return maxElem
|
|
),
|
|
|
|
-- loads an xml document into memory
|
|
fn load filename =
|
|
(
|
|
document = dotNetObject "System.Xml.XmlDocument"
|
|
try(
|
|
document.Load filename
|
|
)catch(
|
|
gRsUlog.LogError ("XML loading failed for file "+filename as string+" due to:"+(getCurrentException()))
|
|
)
|
|
),
|
|
|
|
-- loads a single element into memory
|
|
fn loadElement filename element =
|
|
(
|
|
document = dotNetObject "System.Xml.XmlDocument"
|
|
|
|
try(
|
|
reader = dotNetObject "System.Xml.XmlTextReader" filename
|
|
)catch(
|
|
gRsUlog.LogError ("XML loading failed for file "+filename as string+" due to:"+(getCurrentException()))
|
|
)
|
|
|
|
if (reader.ReadToFollowing(element)) then
|
|
(
|
|
try(
|
|
document.Load(reader.ReadSubtree())
|
|
)catch(
|
|
gRsUlog.LogError ("XML loading failed for file "+filename as string+" due to:"+(getCurrentException()))
|
|
)
|
|
) else (
|
|
gRsUlog.LogWarning ("XML reader can't find element '"+element as string+"' in file "+filename as string)
|
|
)
|
|
reader.Close()
|
|
),
|
|
|
|
fn ParseIntoMaxscripthierarchy =
|
|
(
|
|
maxXmlObject = ParseElementRec document
|
|
)
|
|
)
|
|
|
|
fn RsCreateXmlElement name elemattributes xmldoc = (
|
|
projelem = xmldoc.createelement(name)
|
|
for attribute in elemattributes do (
|
|
attr = xmldoc.createattribute attribute.name
|
|
attr.value = attribute.value as string
|
|
projelem.Attributes.append(attr)
|
|
)
|
|
return projelem
|
|
)
|
|
|
|
fn RsGetXmlElement elem elemsearch all:false = (
|
|
childelems = elem.childnodes
|
|
local retArray = #()
|
|
for i = 0 to ( childelems.Count - 1 ) do (
|
|
childelem = childelems.itemof(i)
|
|
if childelem.name == elemsearch then
|
|
(
|
|
if all then
|
|
append retArray childelem
|
|
else
|
|
return childelem
|
|
)
|
|
)
|
|
if all then
|
|
return retArray
|
|
else
|
|
return undefined
|
|
)
|
|
|
|
-- End of xml2.ms
|
|
-- doc = XmlDocument()
|
|
-- doc.Load "X:/gta5/build/dev/common/data/waterout.xml" |