0

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!

kman
  • 3
  • 5

2 Answers2

0

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>
)
Mark
  • 8,140
  • 1
  • 14
  • 29
  • Thanks for the quick response. Not sure why this is not working, seems to mess up the format of the xml file as well? Maybe I can clarify: I have this: //Content/Catalog/Feature[7]/Option[1]/code=ABC //Content/Catalog/Feature[7]/Option[2]/code=DEF... etc to Option[68] I would like to add: //Content/Catalog/Feature[7]/Option[1]/code=ZZZ Incidentally "code" is an Attribute (if that matters) Thanks for any help you can offer. – kman Jul 29 '16 at 00:06
  • @kman It would help if you update the question to show what you are trying to achieve. Show before/after XML examples of what you want and how it's how it's not working. – Mark Jul 29 '16 at 00:29
  • I updated my message. Here's the second image link: [link] http://www.kwhdesign.ca/Temp/AfterCode.jpg – kman Jul 29 '16 at 18:31
  • @kman Updated my answer - hopefully I am getting closer to what you want to do! :-) – Mark Jul 29 '16 at 19:17
  • OK I am going with the XDocument/Xelement method, time to learn new tricks! It worked perfectly. Thanks Mark and dbasnett for all your help. – kman Jul 29 '16 at 19:37
0

I much prefer using xelement for manipulating XML. Here is an example using xelement. It has several debug statements so you can see what it going on at each step. Hope it helps.

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

    Dim xe As XElement
    'to load from a file
    '  xe = XElement.Load("Your Path Here")

    'for testing you can do this
    xe = <content>
             <Catalog>
                 <feature></feature>
                 <feature></feature>
                 <feature></feature>
                 <feature></feature>
             </Catalog>
         </content>

    'to add an element to the base

    Debug.WriteLine("")
    Debug.WriteLine(xe.ToString)

    xe.AddFirst(New XElement("foo"))

    Debug.WriteLine("")
    Debug.WriteLine(xe.ToString)

    'to add an element to sub element
    Dim optProto As XElement = <option></option>
    Dim addthis As New XElement(optProto) 'note New
    xe.<Catalog>...<feature>.ElementAt(3).Add(addthis)

    Debug.WriteLine("")
    Debug.WriteLine(xe.ToString)

    addthis.Value = "added" 'note

    Debug.WriteLine("")
    Debug.WriteLine(xe.ToString)

End Sub
dbasnett
  • 11,334
  • 2
  • 25
  • 33
  • Thanks dbasnett. I would like to stay with XmlDocument rather than use Xelement. I did try to use XElement and was able to get the results I wanted but found other issues like how to read the value of a single node or count a number of nodes, it is certainly because I am not as familiar with XElement.. I just could not figure out how to do those two simple functions. Thanks again, may end up going back to XElement. – kman Jul 29 '16 at 18:07