Notifications
Clear all

[Closed] XML writing

 MZ1

When I try to run this code:

(
	Address = "C:/MyTest.xml"
	
	XmlDoc=dotNetObject "System.xml.xmlDocument"
	DocEle=XmlDoc.createElement "DocEle"
	XmlDoc.appendChild DocEle
	EmailEle=XmlDoc.createElement "MyEmail@google.com"
	DocEle.appendChild EmailEle
	XmlDoc.save Address
)

This error comes up:

-- Runtime error: dotNet runtime exception: The '@' character, hexadecimal value 0x40, cannot be included in a name.

I don’t know what “hexadecimal value 0x40” is and how I can use “@” in xml nodes name.

19 Replies
1 Reply
(@denist)
Joined: 1 year ago

Posts: 0

0x40 is ASCII code of @ symbol

you can not use @ symbol in xml node or attribute name. but can use it in values.

 MZ1

I changed code to store data in a Attribute, its work.
But it seems searching and finding a attribute value is slower than getting a node by name.

(
	--creating document
	XmlDoc=dotNetObject "System.xml.xmlDocument"
	DocEle=XmlDoc.createElement "DocEle"
	XmlDoc.appendChild DocEle
	for i=1 to 200 do
	(		
		NodeName = "MyNode"+(i as string)
		EmailEle=XmlDoc.createElement NodeName
		EmailEle.setattribute "Name" NodeName
		DocEle.appendChild EmailEle
	)
	
	FindNodeName = "MyNode100"
	
	--find by name:
	start = timeStamp()
	DocEle.item[FindNodeName]
	end = timeStamp()
	format "Find by name took % seconds
" ((end - start) / 1000.0)
	
	--find by attribute:
	start = timeStamp()
	(for i=0 to DocEle.childnodes.count-1 where (Nd = DocEle.childnodes.itemof[i]).getattribute "Name"==FindNodeName collect Nd)[1]
	end = timeStamp()
	format "Find by attribute took % seconds
" ((end - start) / 1000.0)
)
2 Replies
(@denist)
Joined: 1 year ago

Posts: 0

slower. but you can make a node name just replacing the @ symbol with any other string… like “here_is_the_at_sign

 MZ1
(@mz1)
Joined: 1 year ago

Posts: 0

My problem is that string comes from user input(Textbox).
Another question is which method is faster to find a node by attribute:

(
	--creating document
	XmlDoc=dotNetObject "System.xml.xmlDocument"
	DocEle=XmlDoc.createElement "DocEle"
	XmlDoc.appendChild DocEle
	for i=1 to 1000 do
	(		
		NodeName = "MyNode"+(i as string)
		EmailEle=XmlDoc.createElement NodeName
		EmailEle.setattribute "Name" NodeName
		DocEle.appendChild EmailEle
	)
	
	FindNodeName = "MyNode100"
	
--find by attribute(Collect):
	start = timeStamp()
	Childes = DocEle.childnodes
	(for i=0 to Childes.count-1 where (Nd = Childes.itemof[i]).getattribute "Name"==FindNodeName collect Nd)[1]
	end = timeStamp()
	format "Find by attribute(Collect) took % seconds
" ((end - start) / 1000.0)
	
--find by attribute(While):
	start = timeStamp()
	notFound = true
	Childes = DocEle.childnodes
	for i=0 to Childes.count-1 while notFound=true do
	(
		if (Nd = Childes.itemof[i]).getattribute "Name"==FindNodeName do
		(
			notFound = false
			Nd
		)
	)
	end = timeStamp()
	format "Find by attribute(While) took % seconds
" ((end - start) / 1000.0)
)  

you have to look at XPath…

 MZ1

I’m bit confused about xpath.
Please, Correct my code if is not true:

(
	--creating document
	XmlDoc=dotNetObject "System.xml.xmlDocument"
	DocEle=XmlDoc.createElement "DocEle"
	XmlDoc.appendChild DocEle
	
	SubNode=XmlDoc.createElement "SubNode"
	DocEle.appendChild SubNode
	for i=1 to 10 do
	(		
		Nd = XmlDoc.createElement ("Nd"+(i as string))
		Nd.setattribute "Name" ("AttVal"+(i as string))
		SubNode.appendChild Nd
	)
	
-- 	XmlDoc.save "C:/MyTest.xml"

	--find by XPath:
	
	Nd = SubNode.SelectSingleNode("./*[@Name= 'AttVal3']")
	
)

xpath is very powerful but like regex very “syntax rich”. I’ve learned a lot from this site and also wrote a small article about it.

1 Reply
 MZ1
(@mz1)
Joined: 1 year ago

Posts: 0

Very useful article and tutorials, Thank you!
In my case, I want to find child node of specific node by using its attribute.we don’t know its parents xpath.

Getting a node by its attribute with xpath looks like this: //title[@lang=‘eng’]. this will select the title node wherever it is in the xml but only if it has an attribute “lang” with the value “eng”.
If you want all childnodes of that node you’d use: //title[@lang=‘eng’]/*, or if you want a specific childnode called “somename”, you’d use //title[@lang=‘eng’]/somename.

I always keep that site from w3schools open when I work with xpath.

1 Reply
 MZ1
(@mz1)
Joined: 1 year ago

Posts: 0

Your example are great, But maybe I missing something, I’m trying to mimic get single child item by name:

MyNode.item[ItemName] >>> MyNode.item[Attribute]

Well,
if you want even more specific help I’d really need to see the xml you’re working with. Otherwise just look at the w3schools website and figure it out by trial and error. That’s most sustainable anyway.

2 Replies
 MZ1
(@mz1)
Joined: 1 year ago

Posts: 0

This code shows what I want:

(
	--creating document
	XmlDoc=dotNetObject "System.xml.xmlDocument"
	DocEle=XmlDoc.createElement "DocEle"
	XmlDoc.appendChild DocEle
	
	GroupNd=XmlDoc.createElement "Group"
	DocEle.appendChild GroupNd
	
	for i=1 to 10 do
	(		
		Nd = XmlDoc.createElement "Nd"
		Nd.setattribute "Name" ("Name_"+(i as string))
		GroupNd.appendChild Nd
	)
	
	XmlDoc.save "C:/MyTest.xml"
	
	--How I can get a child of GroupNd with Attribute:(Name == "Name_5")?
)

How I can get a child of GroupNd with Attribute:(Name == “Name_5”) ?

(@denist)
Joined: 1 year ago

Posts: 0

it’s


a = xmldoc.selectsinglenode "//*[@Name='Name_5']"

which translating from XPath means: find the first node starting from root, with any name but with attribute “Name” which equals “Name_5”

Darn it, too slow.
If you want to be specific and only want children of Group/Nd with that specific attribute, you’d use

xmlDoc = dotNetObject "system.xml.xmlDocument"
xmlDoc.load "somePath"
 xmlDoc.selectSingleNode "//Group/Nd[@Name='Name_5']"
 MZ1

And what about two group with same structure? How we can get node from second group?

(
	--creating document
	XmlDoc=dotNetObject "System.xml.xmlDocument"
	DocEle=XmlDoc.createElement "DocEle"
	XmlDoc.appendChild DocEle
	
	for i=1 to 2 do
	(
		GroupNd=XmlDoc.createElement "Group"
		DocEle.appendChild GroupNd
		
		for i=1 to 10 do
		(		
			Nd = XmlDoc.createElement "Nd"
			Nd.setattribute "Name" ("Name_"+(i as string))
			GroupNd.appendChild Nd
		)
	)
	XmlDoc.save "C:/MyTest.xml"
)
 MZ1

And what about two group with same structure? How we can get node from second group?

(
	--creating document
	XmlDoc=dotNetObject "System.xml.xmlDocument"
	DocEle=XmlDoc.createElement "DocEle"
	XmlDoc.appendChild DocEle
	
	for i=1 to 2 do
	(
		GroupNd=XmlDoc.createElement "Group"
		DocEle.appendChild GroupNd
		
		for i=1 to 10 do
		(		
			Nd = XmlDoc.createElement "Nd"
			Nd.setattribute "Name" ("Name_"+(i as string))
			GroupNd.appendChild Nd
		)
	)
	XmlDoc.save "C:/MyTest.xml"
)
Page 1 / 2