-2

I am working in a vb.net project, I would like to update an existing XML with a new section,

<BookUpdateable Action="Renew">
    <BookOption>Book</BookOption>
    <BookMaster Action="None">
        <Key>
          <MasterReference>7678812382</MasterReference>
        </Key>
        <Assured Action="Update" xsi:type="OrgDataUpdateable">
          <Key>
            <CaptionCode>BOOKINTRO</CaptionCode>
            <PrevTransaction>0</PrevTransaction>
          </Key>
          <Addresses>
            <IsDeleted>true</IsDeleted>
          </Addresses>
        </Assured>
        <Units>
          <IsDeleted>true</IsDeleted>
        </Units>
        <Sections>
          <SectionDataUpdateable Action="Update" SectionTypeCode="NEW" SubSectionTypeCode="ONE">
            <Key>
              <SectionSequence>10</SectionSequence>
            </Key>
            <IsDeleted>true</IsDeleted>
          </SectionDataUpdateable>
  /*************************************************
  NEW  SECTION TO BE ADDED HERE
  *************************************************/
        </Sections>
        <BookDataExts>
          <MasterStatusCode>BOOKEXTN</MasterStatusCode>
          <EffectiveDate>2017-07-28</EffectiveDate>
        </BookDataExts>
    </BookMaster>
    <ReturnFields>false</ReturnFields>
</BookUpdateable>

I have tried like this, but not working,

nameCodeSections = xDoc.SelectSingleNode("/r:BookUpdateable[1]/r:BookMaster", xNsMgr)
Dim childNode As XmlNode = xDoc.CreateNode(XmlNodeType.Element, "Sections", "")
Dim newAttribute As XmlAttribute = xDoc.CreateAttribute("SectionDataUpdateable", Str, "")
childNode.Attributes.Append(newAttribute)
nameCodeSections.AppendChild(childNode)

I need to insert another section under sections element like this

<SectionDataUpdateable Action="Update" SectionTypeCode="OLD"     SubSectionTypeCode="TWO">
<Key>
<SectionSequence>05</SectionSequence>
</Key>
<IsDeleted>true</IsDeleted>
</SectionDataUpdateable>
Ed Smilovici
  • 194
  • 1
  • 1
  • 12
Partha
  • 11
  • 4
  • Your XML sample is missing the namespace declaration, `xmlns:xsi=...` and hence not well-formed and fails in parsing. – Parfait Jul 04 '17 at 23:15

2 Answers2

1

The location of the text "NEW SECTION TO BE ADDED HERE" in your example suggests that you want the new data to be added as the last sibling to the first <SectionDataUpdateable />. So I used this sample XML:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<BookUpdateable Action="Renew">
    <BookOption>Book</BookOption>
    <BookMaster Action="None">
        <Key>
          <MasterReference>7678812382</MasterReference>
        </Key>
        <Assured Action="Update" xsi:type="OrgDataUpdateable">
          <Key>
            <CaptionCode>BOOKINTRO</CaptionCode>
            <PrevTransaction>0</PrevTransaction>
          </Key>
          <Addresses>
            <IsDeleted>true</IsDeleted>
          </Addresses>
        </Assured>
        <Units>
          <IsDeleted>true</IsDeleted>
        </Units>
        <Sections>
          <SectionDataUpdateable Action="Update" SectionTypeCode="NEW" SubSectionTypeCode="ONE">
            <Key>
              <SectionSequence>10</SectionSequence>
            </Key>
            <IsDeleted>true</IsDeleted>
          </SectionDataUpdateable>
          <SectionDataUpdateable Action="Nothing" SectionTypeCode="TEST" SubSectionTypeCode="ONE">
            <Key>
              <SectionSequence>99</SectionSequence>
            </Key>
            <IsDeleted>dontcare</IsDeleted>
          </SectionDataUpdateable>
          <!--
            /*********************************************
            NEW SECTION TO BE INSERTED BEFORE THIS COMMENT
            *********************************************/
            -->
        </Sections>
        <BookDataExts>
          <MasterStatusCode>BOOKEXTN</MasterStatusCode>
          <EffectiveDate>2017-07-28</EffectiveDate>
        </BookDataExts>
    </BookMaster>
    <ReturnFields>false</ReturnFields>
</BookUpdateable>

Without you defining the xmlns parts in the question to make it easier to answer, I had to make something up for "xsi" and remove the "r:".

One thing I have noticed about manipulating XML is that you often need to act on the parent of a node.

So, get the nodes "/BookUpdateable[1]/BookMaster/Sections/SectionDataUpdateable" and insert your new data after the last one:

Option Infer On
Option Strict On

Imports System.Xml

Module Module1

    Sub Main()
        Dim src = "C:\temp\BookUpdateable.xml"
        Dim dest = "C:\temp\BookUpdateable2.xml"

        Dim xmlDoc As New XmlDocument
        Dim settings = New XmlReaderSettings With {.NameTable = New NameTable()}
        Dim nsm = New XmlNamespaceManager(settings.NameTable)
        nsm.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance")

        Dim context = New XmlParserContext(Nothing, nsm, "", XmlSpace.Default)
        Dim reader = XmlReader.Create(src, settings, context)
        xmlDoc.Load(reader)

        Dim nameCodeSections = xmlDoc.SelectNodes("/BookUpdateable[1]/BookMaster/Sections/SectionDataUpdateable", nsm)

        Dim newData As XElement = <SectionDataUpdateable Action="Update" SectionTypeCode="OLD" SubSectionTypeCode="TWO">
                                      <Key>
                                          <SectionSequence>05</SectionSequence>
                                      </Key>
                                      <IsDeleted>true</IsDeleted>
                                  </SectionDataUpdateable>

        Dim xd = New XmlDocument()
        xd.LoadXml(newData.ToString())

        nameCodeSections(0).ParentNode.InsertAfter(xmlDoc.ImportNode(xd.FirstChild, True), nameCodeSections(nameCodeSections.Count - 1))

        xmlDoc.Save(dest)

        Console.WriteLine("Done.")
        Console.ReadLine()

    End Sub

End Module

The running of which results in:

<?xml version="1.0" encoding="utf-8"?>
<BookUpdateable Action="Renew">
  <BookOption>Book</BookOption>
  <BookMaster Action="None">
    <Key>
      <MasterReference>7678812382</MasterReference>
    </Key>
    <Assured Action="Update" xsi:type="OrgDataUpdateable" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <Key>
        <CaptionCode>BOOKINTRO</CaptionCode>
        <PrevTransaction>0</PrevTransaction>
      </Key>
      <Addresses>
        <IsDeleted>true</IsDeleted>
      </Addresses>
    </Assured>
    <Units>
      <IsDeleted>true</IsDeleted>
    </Units>
    <Sections>
      <SectionDataUpdateable Action="Update" SectionTypeCode="NEW" SubSectionTypeCode="ONE">
        <Key>
          <SectionSequence>10</SectionSequence>
        </Key>
        <IsDeleted>true</IsDeleted>
      </SectionDataUpdateable>
      <SectionDataUpdateable Action="Nothing" SectionTypeCode="TEST" SubSectionTypeCode="ONE">
        <Key>
          <SectionSequence>99</SectionSequence>
        </Key>
        <IsDeleted>dontcare</IsDeleted>
      </SectionDataUpdateable>
      <SectionDataUpdateable Action="Update" SectionTypeCode="OLD" SubSectionTypeCode="TWO">
        <Key>
          <SectionSequence>05</SectionSequence>
        </Key>
        <IsDeleted>true</IsDeleted>
      </SectionDataUpdateable>
      <!--
            /*********************************************
            NEW SECTION TO BE INSERTED BEFORE THIS COMMENT
            *********************************************/
            -->
    </Sections>
    <BookDataExts>
      <MasterStatusCode>BOOKEXTN</MasterStatusCode>
      <EffectiveDate>2017-07-28</EffectiveDate>
    </BookDataExts>
  </BookMaster>
  <ReturnFields>false</ReturnFields>
</BookUpdateable>

You should put in some sanity checks such as testing that nameCodeSections IsNot Nothing before using nameCodeSections(0).

References:

Andrew Morton
  • 24,203
  • 9
  • 60
  • 84
  • Hi, I have tried this. Its working well. But I am facing an issue with that. the new section coming with xmlns="" 99 dontcare – Partha Jul 04 '17 at 20:32
  • @user1508967 The `"xmlns=""` parts are likely to be something to do with code that you didn't show - note that I removed the "r:" parts (c.f. `nameCodeSections = xDoc.SelectSingleNode("/r:BookUpdateable[1]/r:BookMaster", xNsMgr)` in the question) because there was no definition for that in the question. – Andrew Morton Jul 04 '17 at 20:43
0

Consider XSLT, the special-purpose language designed to transform XML files such as your update section needs. Like most general-purpose languages including Java, Python, C#, PHP, VB.Net can run XSLT 1.0 scripts with various libraries. Here, no looping, parsing, or conditional logic is needed.

I have been known to advocate XSLT across several programming threads. So, while I know nothing of VB.Net, I do include code below from provided MSDN source. Please adjust as needed.

XSLT (save as .xsl file which is a well-formed .xml file and can be loaded from file or string)

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <!-- Identity Transform -->
    <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
    </xsl:template>

    <!-- Add New SectiondataUdpateable -->
    <xsl:template match="Sections">
     <xsl:copy>
       <xsl:copy-of select="*"/>
       <SectionDataUpdateable Action="Update" SectionTypeCode="OLD" SubSectionTypeCode="TWO">
       <Key>
         <SectionSequence>05</SectionSequence>
       </Key>
       <IsDeleted>true</IsDeleted>
       </SectionDataUpdateable>
     </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

VB.NET (see MSDN implementation)

'Create the XslTransform object.
Dim xslt as XslTransform = new XslTransform()

'Load the stylesheet.
xslt.Load("XSLTScript.xsl")

'Transform the file.
xslt.Transform("Input.xml", "Output.xml")

XML Output (xmlns:xsi="www.example.com" declaration added in input)

<BookUpdateable xmlns:xsi="www.example.com" Action="Renew">
  <BookOption>Book</BookOption>
  <BookMaster Action="None">
    <Key>
      <MasterReference>7678812382</MasterReference>
    </Key>
    <Assured Action="Update" xsi:type="OrgDataUpdateable">
      <Key>
        <CaptionCode>BOOKINTRO</CaptionCode>
        <PrevTransaction>0</PrevTransaction>
      </Key>
      <Addresses>
        <IsDeleted>true</IsDeleted>
      </Addresses>
    </Assured>
    <Units>
      <IsDeleted>true</IsDeleted>
    </Units>
    <Sections>
      <SectionDataUpdateable Action="Update" SectionTypeCode="NEW" SubSectionTypeCode="ONE">
        <Key>
          <SectionSequence>10</SectionSequence>
        </Key>
        <IsDeleted>true</IsDeleted>
      </SectionDataUpdateable>
      <SectionDataUpdateable Action="Update" SectionTypeCode="OLD" SubSectionTypeCode="TWO">
        <Key>
          <SectionSequence>05</SectionSequence>
        </Key>
        <IsDeleted>true</IsDeleted>
      </SectionDataUpdateable>
    </Sections>
    <BookDataExts>
      <MasterStatusCode>BOOKEXTN</MasterStatusCode>
      <EffectiveDate>2017-07-28</EffectiveDate>
    </BookDataExts>
  </BookMaster>
  <ReturnFields>false</ReturnFields>
</BookUpdateable>
Parfait
  • 104,375
  • 17
  • 94
  • 125