Search code examples
xmlvb.netelementxelement

Adding XmlElement to a non-root node list using VB.NET


I'm trying to add a new element to an existing list of elements in an XML file. I'm using this code to initiate the Element:

    Dim newElem As XmlElement = doc.CreateElement("/Content/Catalog/Feature[7]/Option")

But I get an error message saying I can't use the "/" character. Not sure how to resolve this?

UPDATE: I'm adding two images, the 1st is a view of the XML file and where the data resides. File:OriginalXML The highlighted in blue items are what I am wanted to add (does not have to be at the top of the list, appending the data is probably better). The DisplayName, MultiMedia and CustomData as simple CDATA text. The second file is what happens when I run your code. (AfterCode.jpg). Note the highlighted "Option" seems to be in the wrong place and the formatting is lost. If you want to look at the original XML file, here it is: http://www.kwhdesign.ca/Temp/paf.xml

![OriginalXML] http://www.kwhdesign.ca/Temp/OriginalXML.jpg

(I can't post more than 2 links, so I'll try the second image in another comment)

Hope this helps! thanks again!


Solution

  • Create the element, then add it where you want it with AppendChild:

    Dim newElem As XmlElement = doc.CreateElement("Option")
    doc.SelectSingleNode("/Content/Catalog/Feature[7]").AppendChild(newElem)
    

    UPDATE

    It's still not entirely clear what you are wanting to do, but if you want to insert a new <Option> element after the last existing <Option> then something like this would be a start, although I think it shows how tedious this will be (although it's entirely possible there is an easier way to generate the new option)!

    Dim newOption = doc.CreateElement("Option")
    newOption.SetAttribute("code", "ZZZ")
    Dim displayName = doc.CreateElement("DisplayName")
    displayName.SetAttribute("lang", "en-US")
    displayName.AppendChild(doc.CreateCDataSection("This is a test"))
    newOption.AppendChild(displayName)
    Dim feature = doc.SelectSingleNode("/Content/Catalog/Feature[7]")
    Dim lastOption = feature.SelectSingleNode("Option[last()]")
    feature.InsertAfter(newOption, lastOption)
    

    Like @dbasnett, I would prefer XDocument/XElement and LINQ to XML. Adding a new <Option> would then be something like this (note that indexes are 0 based here, unlike in XPath):

    Dim doc = XDocument.Load("paf.xml")
    doc.<Content>.<Catalog>.<Feature>(6).<Option>.Last().AddAfterSelf(
      <Option code="ZZZ">
        <DisplayName lang="en-US"><![CDATA[This is a test]]></DisplayName>
        <Multimedia type="MediumImage"><![CDATA[Multimedia\Pictures\Medium\SherwinWilliams.jpg]]></Multimedia>
        <Multimedia type="LargeImage"><![CDATA[Multimedia\Pictures\Large\SherwinWilliams.jpg]]></Multimedia>
        <CustomData><![CDATA[<xml>
      <RECKEY code="010201650004001V" />
      <VARProp VarID="1237" PropID="Expression" Expr="SHERW" />
      <VARProp VarID="3518" PropID="Expression" Expr="SHERW" />
      <VARProp VarID="3580" PropID="Expression" Expr="SHERW" />
      <VARProp VarID="2149" PropID="VariableType" Expr="104" />
    </xml>]]></CustomData>
      </Option>
    )