Manipulate XML file

Hi ...

a bit stuck with this ...

in my case, I want to replace the old value with a new value via Dotnet

this is XML view

the value of the sphere is a target to be changed

what I want to do is simple,... replace a "sphere" value with a "plane"

--------------------------------------------------------------------------------------------------- Initial
--Load the xml assembly
dotNet.loadAssembly "system.xml"
--Create an xml document object.
xmlDoc=dotNetObject "system.xml.xmlDocument"
 
--Open the file in Max to see the file. 
filename="C:\\BGtest.xml" -- ((getDir #autoback)+"\\BGtest.xml")
 
--------------------------------------------------------------------------------------------------- Load document
	--Load the XML file.
	xmlDoc.load filename
--------------------------------------------------------------------------------------------------- read document
	--Check to make sure the xmlDoc has a root element. 
	docEle=xmlDoc.documentElement
	clearListener()
	format "Element Name: %\n\n" docEle.name
 
	--Check a target attribute value called name
	objNameStr=(docEle.ChildNodes.itemOf[0].GetAttributeNode "name").value
	format "Node Name: %\n\n" objNameStr
 
	--Check a target attribute value called class
	objClassStr=(docEle.ChildNodes.itemOf[0].GetAttributeNode "class").value
        format "Node class: %\n\n" objClassStr
 
--------------------------------------------------------------------------------------------------- Manipulate document
	--Want to replace "sphere" to "Plane"  but it's doesn't work correctly
	docEle.ChildNodes.itemOf[0].SetAttributeNode "name" "Plane001" --$.name
	docEle.ChildNodes.itemOf[0].SetAttributeNode "class" "Plane" --classOf $ as string
 
--------------------------------------------------------------------------------------------------- save and open document
xmlDoc.save filename
edit filename -- to see the result

so i tried but still not working

any suggestion ?

attached example xml...

thanks

AttachmentSize
xml_targetnone.jpg41.12 KB
bgtest.rar167 bytes

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Budi G's picture

hi Branko... thanks for some

hi Branko...
thanks for some links and your scripts ;)

correct, I got the point of what I needed...

after checking your script, the problem can be solved

--Load the xml assembly
dotNet.loadAssembly "system.xml"
--Create an xml document object.
xmlDoc=dotNetObject "system.xml.xmlDocument"
 
--Open the file in Max to see the file. 
filename="C:\\BGtest.xml"
 
--------------------------------------------------------------------------------------------------- Load document
	--Load the XML file.
	xmlDoc.load filename
--------------------------------------------------------------------------------------------------- read document
	--Check to make sure the xmlDoc has a root element. 
	docEle=xmlDoc.documentElement
	clearListener()
	format "Element Name: %\n\n" docEle.name
 
	--Check a target attribute value called name
	objNameStr=(docEle.ChildNodes.itemOf[0].GetAttributeNode "name").value
	format "Node Name: %\n\n" objNameStr
 
	--Check a target attribute value called class
	objClassStr=(docEle.ChildNodes.itemOf[0].GetAttributeNode "class").value
        format "Node class: %\n\n" objClassStr
 
--------------------------------------------------------------------------------------------------- Manipulate document
	--Reject this code
	--docEle.ChildNodes.itemOf[0].SetAttributeNode "name" "Plane001" --$.name
	--docEle.ChildNodes.itemOf[0].SetAttributeNode "class" "Plane" --classOf $ as string
 
	-- Correct, to replace "sphere" with "Plane"
	docEle.ChildNodes.Item[0].Attributes.ItemOf["name"].value = "Plane001"
	docEle.ChildNodes.Item[0].Attributes.ItemOf["class"].value = "Plane"
 
--------------------------------------------------------------------------------------------------- save and open document
xmlDoc.save filename
edit filename -- to see the result

glad to see the results

thank you very much man

barigazy's picture

...

My pleasure.
BTW using XPath you can easely and fast edit any xml file.
I tried to use it but without luck. Maybe next time :)

barigazy

Budi G's picture

sounds a good thing... but I

sounds a good thing...
but I hold information about XPath first.
a new language is enough to make me busy for a while. :D
I'm currently finishing another script, yeah maybe next time.

barigazy's picture

...

Maybe this method will help

--Collect scene nodes and classes
objsList = for o in geometry where o != TargetObject collect #(o.name, getClassName o)
--xml file (change if you want)
xmlFileName = getdir #scripts + "\\BGtest.xml"
--With this fn you can easely create xml elements
fn xmlCreator dnXML: prtNode: tagName: innerTxt: attArr: make:#xmlElement =
(
	local tag = if make != #xmlComment then (dnXML.createElement tagName) else (dnXML.createComment tagName)
	prtNode.AppendChild tag
	if innerTxt != unsupplied do tag.InnerText = innerTxt
	if attArr != unsupplied do (for i = 1 to attArr.count do tag.SetAttribute attArr[i][1] attArr[i][2]) ; tag
)
-- store all data in xml
fn saveXML xmlFile: data: = if objsList.count != 0 do
(
	local xmldoc = dotNetObject "System.Xml.XmlDocument"
	root = xmlCreator dnXML:xmldoc prtNode:xmldoc tagName:"Node_Collector" \
	attArr:#(#("version","1.0"), #("author","Budi Gunawan"), #("website","http://bg-script.blogspot.com/"))
	nodes = xmlCreator dnXML:xmldoc prtNode:root tagName:"Nodes_List"
	comment_1 = xmlCreator dnXML:xmldoc prtNode:nodes tagName:"This list represents all scene geometry nodes" make:#xmlComment
	for i = 1 to data.count do
	(		
		xmlCreator dnXML:xmldoc prtNode:nodes tagName:("n_" + ((i-1) as String)) \
		attArr:#(#("name", data[i][1]), #("class", (data[i][2] as String)))
	)
	info = xmlCreator dnXML:xmldoc prtNode:root tagName:"Object_Info"
	comment_2 = xmlCreator dnXML:xmldoc prtNode:info tagName:"Usual Scene Info." make:#xmlComment
	count = xmlCreator dnXML:xmldoc prtNode:info tagName:"Scene_Objects_Count" innerTxt:(objsList.count as String)
	ltime = xmlCreator dnXML:xmldoc prtNode:info tagName:"Local_Time" innerTxt:localtime
	xmldoc.Save xmlFile
	edit xmlFile
)
saveXML xmlFile:xmlFileName data:objsList

barigazy

barigazy's picture

...

Now we need to load xml

-- load xml
fn getValueByRootEle rootEl: tagName: attName: =
(
	local idx = undefined
	for i = 1 to rootEl.ChildNodes.count-1 where rootEl.ChildNodes.ItemOf[i].name == tagName do idx = i
	if idx != null then rootEl.ChildNodes.Item[idx].Attributes.ItemOf[attName].value else idx
)
xmlFileName = getdir #scripts + "\\BGtest.xml"
xmldoc = dotNetObject "System.Xml.XmlDocument"
xmldoc.Load xmlFileName
rootEle = xmldoc.DocumentElement
nList = rootEle.Item["Nodes_List"]
oInfo = rootEle.Item["Object_Info"]
-- get some values from xml file
n2class = getValueByRootEle rootEl:nList tagName:"n_2" attName:"class"
n3name = getValueByRootEle rootEl:nList tagName:"n_3" attName:"name"
oc = (oInfo.Item["Scene_Objects_Count"].InnerText) as Integer
lt = (oInfo.Item["Local_Time"].InnerText)

According to this u can create new fn for setting new values for docElements with
couple attributes.(similar to "getValueByRootEle" fn) :)
To change let say *Scene_Objects_Count* U can use this

-- close first file if is opened in mxs editor
oInfo.Item["Scene_Objects_Count"].InnerText = "1856"
xmldoc.Save xmlFileName

barigazy

barigazy's picture

...

Also you can look inside code of *ScriptRun* tool where I used similar method for storing some script settings.
Another useful method can be achived with XPath

barigazy

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.