I have an xml file DataConfiguration.xml with this entry
<DataSource>
<localdata>
<add context="Localization">
<parameter name="timeout" type="int" defaultvalue="60"/>
<parameter name="address" type="string" defaultvalue="192.168.9.45" />
<parameter name="port" type="int" defaultvalue="6789"/>
</add>
</localdata>
</DataSource>
I need to add another entry to "localdata" so it would be
<DataSource>
<localdata>
<add context="Localization">
<parameter name="timeout" type="int" defaultvalue="60"/>
<parameter name="address" type="string" defaultvalue="192.168.9.45" />
<parameter name="port" type="int" defaultvalue="6789"/>
</add>
<add context="General">
<parameter name="timeout" type="int" defaultvalue="60"/>
<parameter name="address" type="string" defaultvalue="192.168.9.478" />
<parameter name="port" type="int" defaultvalue="5674"/>
</add>
</localdata>
</DataSource>
How would I add this in vbscript?
My Current code
'created xml file object
Set xmlDoc = CreateObject("Msxml2.DOMDocument")
xmlDoc.async = False
xmlDoc.preserveWhiteSpace= True
xmlDoc.load("DataConfiguration.xml")
Dim entry
entry = "<add context=""General"">" & _
<parameter name=""timeout"" type=""int"" defaultvalue=""60""/>" & _
<parameter name=""address"" type=""string"" defaultvalue=""192.168.9.478"" />" & _
<parameter name=""port"" type=""int"" defaultvalue=""5674""/>"& _
</add>"
Set NewNode = xmlDoc.createElement(entry)
Set ElemList = xmlDoc.getElementsByTagName("localdata")
ElemList.appendChild(NewNode)
But this give the error
This name may not contain < character" at " Set NewNode = xmlDoc.createElement(entry)
Also the ElemList.appendChild(NewNode) does not work.
XmlDocument.CreateElement accepts three params: a node type, a node name, and a namespace.
In your example, since your child element is named "add", it's an element (type==1), and it is part of the global xml namespace, you would call xmlDoc.CreateElement(1, "add", "")
.
That gives you an empty element. To insert the data you want (the Context="General"
attribute, and all the child elements), you'd then need to make successive calls to the DOM manipulation methods, to add in each child element, each attribute, and so on. Pretty laborious.
But you already have the xml fragment as a string. So instead of creating the element using DOM methods, what you can do is create a 2nd XmlDocument and tell it to get its content from the string. Then grab the documentElement from that 2nd doc. Then call appendChild on the appropriate node in first doc, passing the documentElement from the 2nd doc.
something like this:
Function GetElementFromXmlString(xmlString)
Dim doc
set doc = CreateObject("Msxml2.DOMDocument.6.0")
doc.async = False
doc.preserveWhiteSpace= False
doc.loadXML(xmlString)
Set GetElementFromXmlString = doc.documentElement
End Function
Sub Main()
Set doc1 = CreateObject("Msxml2.DOMDocument.6.0")
doc1.async = False
doc1.preserveWhiteSpace= False ' True
doc1.load("DataConfiguration.xml")
' generate an Element from an XML string
Dim xmlString
xmlString = "<add context=""General"">" & _
" <parameter name=""timeout"" type=""int"" defaultvalue=""60""/>" & _
" <parameter name=""address"" type=""string"" defaultvalue=""192.168.9.478"" />" & _
" <parameter name=""port"" type=""int"" defaultvalue=""5674""/>"& _
"</add>"
Dim newElt
Set newElt = GetElementFromXmlString(xmlString)
' get the first child node of type=Element under the document root element in
' doc1. This is not the same as doc1.documentElement.firstChild. There can
' be text nodes, etc.
Dim node1
Set node1 = doc1.documentElement.selectSingleNode("./*[position()=1]")
' append the element to the node
node1.appendChild(newElt)
WScript.echo (PrettyPrintXml (doc1))
End Sub
Main()
...where the PrettyPrintXml function is defined like this:
Function PrettyPrintXml(xmldoc)
Dim reader
set reader = CreateObject("Msxml2.SAXXMLReader.6.0")
Dim writer
set writer = CreateObject("Msxml2.MXXMLWriter.6.0")
writer.indent = True
writer.omitXMLDeclaration = True
reader.contentHandler = writer
reader.putProperty "http://xml.org/sax/properties/lexical-handler", writer
reader.parse(xmldoc)
PrettyPrintXml = writer.output
End Function
The output of this, for me, is:
<DataSource>
<localdata>
<add context="Localization">
<parameter name="timeout" type="int" defaultvalue="60"/>
<parameter name="address" type="string" defaultvalue="192.168.9.45"/>
<parameter name="port" type="int" defaultvalue="6789"/>
</add>
<add context="General">
<parameter name="timeout" type="int" defaultvalue="60"/>
<parameter name="address" type="string" defaultvalue="192.168.9.478"/>
<parameter name="port" type="int" defaultvalue="5674"/>
</add>
</localdata>
</DataSource>