1

I have an XML document similar to the structure below. Using visual basic how can I insert nodes at the different levels depending on Id & Name.

does Xpath allow me to insert new nodes or does it only allow the modification of existing nodes? so for example if I wanted to add <BuildingPart Id="B012" Name="Bedroom" Type="Room"/> after "B011 Bathroom" how can this be achieved?

<Buildings>
    <BuildingPart Id="B001" Name="House">
        <BuildingPart Id="B002" Name="Level 1" Type="Level">
            <BuildingPart Id="B003" Name="Kitchen" Type="Room"/>
            <BuildingPart Id="B004" Name="Bedroom" Type="Room"/>
            <BuildingPart Id="B005" Name="Lounge" Type="Room"/>
            <BuildingPart Id="B006" Name="Bathroom" Type="Room"/>
        </BuildingPart>
        <BuildingPart Id="B007" Name="Level 2" Type="Level">
            <BuildingPart Id="B008" Name="Bedroom" Type="Room"/>
            <BuildingPart Id="B009" Name="Bedroom" Type="Room"/>
            <BuildingPart Id="B010" Name="Study" Type="Room"/>
            <BuildingPart Id="B011" Name="Bathroom" Type="Room"/>
        </BuildingPart>
    </BuildingPart>
</Buildings>

Thanks.

3
  • 1
    XPath doesn't allow you to insert new nodes or modify existing nodes. Instead, you could use something like XSLT to transform your input XML to a modified output, including additional elements. Commented Jun 14, 2013 at 14:42
  • Im using Xpath just to navigate to corresponding node then with that node do something. wouldnt the appendChild method of the XmlDocumnet class work once I have navigated to node? Commented Jun 17, 2013 at 9:07
  • Yes, if you're using DOM / XmlDocument, that would be one way to do it. (You would have to create the child element first, using CreateElement, as SysDragon showed.) You would then need to output the modified DOM to a file presumably. Commented Jun 17, 2013 at 10:55

1 Answer 1

2

Try this:

Dim doc As Xml.XmlDocument
Dim myNode As Xml.XmlNode

doc.Load(sFileName)

myNode = doc.GetElementById("B001").Clone()
myNode.Attributes("Id").Value = "B012"
myNode.Attributes("Name").Value = "Bedroom"
myNode.Attributes("Type").Value = "Room"

doc.GetElementById("B007").AppendChild(myNode)

EDIT:

To create the node from the begging without cloning simply:

myNode = doc.CreateElement("BuildingPart")

myNode.SetAttribute("Id", "B012")
myNode.SetAttribute("Name", "Bedroom")
myNode.SetAttribute("Type", "Room")

EDIT:

As seen in MSDN Documentation you need to specify always which element is the ID for an element in order to use GetElementById:

The DOM implementation must have information which defines which attributes are of type ID. Although attributes of type ID can be defined in either XSD schemas or DTDs, this version of the product only supports those defined in DTDs. Attributes with the name "ID" are not of type ID unless so defined in the DTD. Implementations where it is unknown whether the attributes are of type ID are expected to return Nothing.

In order to do that, you can add at the beggining of your xml this code:

<!DOCTYPE Buildings[
<!ELEMENT BuildingPart ANY>
<!ATTLIST BuildingPart Id ID #REQUIRED>]>

If you cannot change the file, you have to loop through the elements and check the id from the attributte:

For Each elem As XmlElement In doc.GetElementsByTagName("BuildingPart")
    If elem.GetAttribute("Id").Equals("B007") Then
        elem.AppendChild(myNode)
        Exit For
    End If
Next
Sign up to request clarification or add additional context in comments.

7 Comments

I get a Nullreferenceexception was unhandled error on line "myNode = doc.GetElementById("B001").Clone()". would I be correct in saying that its null because it cant find anything with specified Id? even though Ids are exactly as written above
Of course. Instead of cloning a node, try to create a new one from the begging. I edit my asnwer.
using your editted code, there is no function title "SetAttribute" for the myNode element. also, I still need a way to insert the new node into the document because the GetElementById always throws a nullreference exception
If it throws a NullReferenceException is because the id doesnt exists. And if you use the second edited part, create the var myNode as Xml.XmlElement istead of Node
Something is juts not right, my code is as follows 'imports system.xml' 'Dim doc As New XmlDocument' 'Dim myNode As XmlElement' 'doc.Load("c:\project xml\Project.xml")' 'myNode = doc.CreateElement("BuildingPart")' 'myNode.SetAttribute("Id", "B012")' 'myNode.SetAttribute("Name", "Bedroom")' 'myNode.SetAttribute("Type", "Room")' 'doc.GetElementById("B007").AppendChild(myNode)' and the XML is exactly as written above with the addition of '<?xml version="1.0" encoding="utf-8"?>' at the top
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.