Link to home
Start Free TrialLog in
Avatar of Chethan Bangera
Chethan Bangera

asked on

adding a new node and a value to a XML file and order them in ascending order

Dears,

I have a XML file with content as below.

<?xml version="1.0" encoding="utf-8"?>
<!--Informations Vendor="XXX S.A."-->
<City>
      <Region>
            <Name>001</Name>
            <Name>002</Name>
            <Name>004</Name>
            <Name>005</Name>
      </Region>
</City>

Now, I need a VB script, which adds a <name> node with value '003' in an ascending order.

And the final content of the XML must look as below.

<?xml version="1.0" encoding="utf-8"?>
<!--Informations Vendor="XXX S.A."-->
<City>
      <Region>
            <Name>001</Name>
            <Name>002</Name>
                <Name>003</Name>
            <Name>004</Name>
            <Name>005</Name>
      </Region>
</City>

Please guide me how to write a VB script code for this.
I am struggling to do it for the time being. Your help is highly appreciated.
Avatar of Ryan Chong
Ryan Chong
Flag of Singapore image

try 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

Function PrettyPrintXml(xmldoc, header)
	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 = header & writer.output
End Function

Sub Main()
	Dim XMLSource
	XMLSource = "D:\yourpath\test.xml"
	Dim XMLTarget
	XMLTarget = "D:\yourpath\test.xml"
	
    Set doc1 = CreateObject("Msxml2.DOMDocument.6.0")
    doc1.async = False
    doc1.preserveWhiteSpace= False
    doc1.load(XMLSource)
	
	Dim xmlString
    xmlString = "<Name>003</Name>"
    Dim newElt
    Set newElt = GetElementFromXmlString(xmlString)

    Dim parentNode
    Set parentNode = doc1.documentElement.selectSingleNode("./*[position()=1]")
	Dim preNode
    Set preNode = doc1.documentElement.selectSingleNode("Region/*[position()=3]")
	
	parentNode.insertBefore newElt, preNode
	
	Set output = WScript.CreateObject("Msxml2.DOMDocument.6.0")
	output.loadXML PrettyPrintXml(doc1, "<?xml version=""1.0"" encoding=""utf-8""?>" & vbCrlf)
	
	output.Save(XMLTarget)
End Sub


Main()

msgbox "Done!"

Open in new window


content of test.xml:

<?xml version="1.0" encoding="utf-8"?>
<!--Informations Vendor="XXX S.A."-->
<City>
	<Region>
		<Name>001</Name>
		<Name>002</Name>
		<Name>004</Name>
		<Name>005</Name>
	</Region>
</City>

Open in new window

Avatar of Chethan Bangera
Chethan Bangera

ASKER

@Ryan Chong, Is this a VB script code? Whatever details I have provided is just an example. Instead of 003, the text can be 004a or ABC or anything. The ultimate goal is to insert the value in alphabetical ascending order into the XML.

Few questions:
1. I have a XML in which <Name> tags are already in ascending order. Now the new Text which I am trying to insert must get inserted at the right place. Does this script support the above feature?

2. What is 'xmlString' in the provided script?

3.What are 'xmldoc' and 'header'?

Thanks in advance for clarifying my doubts.
Is this a VB script code?
yes, have you tried run the code?

The ultimate goal is to insert the value in alphabetical ascending order into the XML.
what if the values didn't contain sequential values? i think it would be difficult to "guess" the next missing value.
@Ryan Chong, thank you for the code and for your inputs.

I tried to run the code.
unfortunately, the value is getting appended at the end.

I have written a basic code as follows. In this I am able to add the value too. Here also, it is getting appended at the end.
I am trying to swap the values. But it isn't working. I kindly request you to modify my swap script as it is not working currently.
'----------------------------------------
Sub OnClick()

' Create XML DOM object, load file
Set xmlDoc = CreateObject("Microsoft.XMLDOM")
xmlDoc.Async = "False"
xmlDoc.Load("\\Client\D$\Projectlistxml\projectlist\Test.xml")

' Add nodes
Set objNodeList = xmlDoc.GetElementsByTagName("Name")
Set nNode = xmlDoc.SelectSingleNode("//City/Region")
Set objFieldValue = xmlDoc.CreateElement("Name")
objFieldValue.Text = "003"

For i = 1 To objNodeList.Length - 1 Step 1
'    Msgbox objNodeList(i).Text & ":" & objFieldValue.Text
        If objNodeList(i).Text = objFieldValue.Text Then
                              Flag = 1
                        Else
                              Flag = 0
                        End If
Next
   
If Flag = 1 Then

                                                Msgbox "The project name already exists in the direct access XML"
                                                'Exit Sub
                                                
Else

                                                nNode.AppendChild objFieldValue
                                                
                                                Done = False
                                                While Not Done
                                                    Done = True
                                                    For i = 1 To objNodeList.Length - 1 Step 1
                                                        If objNodeList(i).Text < objNodeList(i-1).Text Then
                                                        Msgbox 1
                                                            Swap = objNodeList(i).Text
                                                            objNodeList(i).Text = objNodeList(i-1).Text
                                                            objNodeList(i-1).Text = Swap
                                                            Done = False
                                                        End If
                                                    Next
                                                Wend
                                                
                                                
                                                Msgbox "The project name got updated in the direct access XML successfully"

End If

End Sub
can you post the sample of

\\Client\D$\Projectlistxml\projectlist\Test.xml

is it exactly the same as what showing in ID: 42282071?
Yes. It is exactly the same. I mean the contents might change. The Name tags might have any values. But they are sorted already.

For example, the Test.xml file can also be like below.

<?xml version="1.0" encoding="utf-8"?>
<!--Informations Vendor="XXX S.A."-->
<City>
      <Region>
            <Name>001</Name>
            <Name>002ABC</Name>
            <Name>ABC</Name>
            <Name>DEF</Name>
      </Region>
</City>

Here, every Name node text is already sorted in ascending order. Now, say if I have to enter, <Name>001XYZ</Name> then the script must enter this value at second position as per the ascending order and my final output Test.xml file must look as below:

<?xml version="1.0" encoding="utf-8"?>
<!--Informations Vendor="XXX S.A."-->
<City>
      <Region>
            <Name>001</Name>
            <Name>001XYZ</Name>
            <Name>002</Name>
            <Name>004</Name>
            <Name>005</Name>
      </Region>
</City>
Small change in my previous comment:

My final XML must look as below:

<?xml version="1.0" encoding="utf-8"?>
<!--Informations Vendor="XXX S.A."-->
<City>
      <Region>
            <Name>001</Name>
            <Name>001XYZ</Name>
            <Name>002ABC</Name>
            <Name>ABC</Name>
            <Name>DEF</Name>
      </Region>
</City>
this is what i have revised for your requirement.

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

Function PrettyPrintXml(xmldoc, header)
	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 = header & writer.output
End Function

Sub Main()
	Dim XMLSource
	XMLSource = "D:\yourpath\test.xml"
	Dim XMLTarget
	XMLTarget = "D:\yourpath\test.xml"
	
	value = InputBox("Please enter a value to be inserted", "Enter Value")
	do while trim(value) = ""
		value = InputBox("Please enter a value to be inserted", "Enter Value")
	loop
	
    Set doc1 = CreateObject("Msxml2.DOMDocument.6.0")
    doc1.async = False
    doc1.preserveWhiteSpace= False
    doc1.load(XMLSource)
	
	Set nodelist = doc1.GetElementsByTagName("Name")
	nodeidx = 1
	For i = 0 To nodelist.Length - 1
		if value > nodelist(i).Text then
			nodeidx = nodeidx + 1
		end if
	Next
	
	Dim xmlString
    xmlString = "<Name>"+value+"</Name>"
    Dim newElt
    Set newElt = GetElementFromXmlString(xmlString)

    Dim parentNode
    Set parentNode = doc1.documentElement.selectSingleNode("./*[position()=1]")
	Dim preNode
    Set preNode = doc1.documentElement.selectSingleNode("Region/*[position()=" & nodeidx & "]")
	
	parentNode.insertBefore newElt, preNode
	
	Set output = WScript.CreateObject("Msxml2.DOMDocument.6.0")
	output.loadXML PrettyPrintXml(doc1, "<?xml version=""1.0"" encoding=""utf-8""?>" & vbCrlf)
	
	output.Save(XMLTarget)
End Sub


Main()

msgbox "Done!"

Open in new window

Thanks for your continuous support.

But, unfortunately, the values are getting appended at the end.
Example:

Here I tried to insert 0033 text and as shown below and it got inserted at the end. Whereas, it should have got inserted between       ->      <Name>002</Name> and <Name>006</Name>

<?xml version="1.0" encoding="utf-8"?>
<!--Informations Vendor="XXXS.A."-->
<City>
      <Region>
            <Name>001</Name>
            <Name>002</Name>
            <Name>006</Name>
            <Name>010</Name>
            <Name>011</Name>
            <Name>ABC</Name>
            <Name>0033</Name>
      </Region>
</City>
i'm using the exact code in ID: 42295026 and it's working fine to me.

<?xml version="1.0" encoding="utf-8"?>
<!--Informations Vendor="XXXS.A."-->
<City>
      <Region>
            <Name>001</Name>
            <Name>002</Name>
            <Name>0033</Name>
            <Name>006</Name>
            <Name>010</Name>
            <Name>011</Name>
            <Name>ABC</Name>
      </Region>
</City>
This question needs an answer!
Become an EE member today
7 DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform.
View membership options
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.