VB.NET使用新部分更新现有XML

时间:2017-07-04 15:56:43

标签: xml vb.net

我在vb.net项目中工作,我想用新的部分更新现有的XML,

<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>

我试过这样,但没有工作,

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)

我需要在像

这样的sections元素下插入另一个部分
<SectionDataUpdateable Action="Update" SectionTypeCode="OLD"     SubSectionTypeCode="TWO">
<Key>
<SectionSequence>05</SectionSequence>
</Key>
<IsDeleted>true</IsDeleted>
</SectionDataUpdateable>

2 个答案:

答案 0 :(得分:1)

在您的示例中,文本“要添加的新部分”的位置表明您希望将新数据添加为第一个<SectionDataUpdateable />的最后一个兄弟。所以我使用了这个示例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>

如果没有您在问题中定义xmlns部分以便于回答,我必须为“xsi”创建一些内容并删除“r:”。

我注意到有关操纵XML的一件事是你经常需要对节点的父节点进行操作。

因此,获取节点“/ BookUpdateable [1] / BookMaster / Sections / SectionDataUpdateable”并在最后一个之后插入新数据:

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

其运行导致:

<?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>

在使用nameCodeSections IsNot Nothing之前,您应该进行一些完整性检查,例如测试nameCodeSections(0)

参考文献:

答案 1 :(得分:0)

考虑XSLT,这是专门用于转换XML文件的专用语言,例如您的更新部分需要。像大多数通用语言一样,包括Java,Python,C#,PHP,VB.Net可以运行带有各种库的XSLT 1.0脚本。这里,不需要循环,解析或条件逻辑。

我已经知道在几个编程线程中提倡XSLT。所以,虽然我对VB.Net一无所知,但我确实在提供的MSDN源代码中包含了以下代码。请根据需要调整。

XSLT (另存为.xsl文件,它是格式良好的.xml文件,可以从文件或字符串加载)

>>> match("honey", "eeehanoey")
True
>>> match("rapture", "aaepprut")
False

VB.NET (见MSDN implementation

<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>

XML 输出(xmlns:xsi =&#34; www.example.com&#34;输入中添加了声明)

'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")