【问题标题】:Insert node in xml document using c#使用c#在xml文档中插入节点
【发布时间】:2018-05-22 20:58:44
【问题描述】:

我试图在 XML 文档中的特定位置插入一个 XML 节点。

这是我的 xml:

<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
    <Body>
        <readContract xmlns="http://implementation.company.schema.reference">
            <ContactNumbers>10158</ContactNumbers>
            <productGroups>0085</productGroups>
            <indicationBalanceInfo>false</indicationBalanceInfo>
            <indicationBlocked>true</indicationBlocked>
        </readContract>
    </Body>
</Envelope>

我正在尝试在标签&lt;productGroups&gt;0085&lt;/productGroups&gt;下方插入另一个标签&lt;productGroups&gt;0093&lt;/productGroups&gt;

期待如下:

<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
    <Body>
        <readContract xmlns="http://implementation.company.schema.reference">
            <ContactNumbers>10158</ContactNumbers>
            <productGroups>0085</productGroups>
            <productGroups>0093</productGroups>
            <indicationBalanceInfo>false</indicationBalanceInfo>
            <indicationBlocked>true</indicationBlocked>
        </readContract>
    </Body>
</Envelope>

使用下面的C#代码来实现。

XmlDocument doc = new XmlDocument();
string inputxml = this.StServiceCallActivity5.InputEnvelope.InnerXml.ToString();
//Here inputxml contains whole xml document.
string addxml = "<productGroups>0093</productGroups>";
doc.LoadXml(inputxml);
XmlDocumentFragment xmlDocFrag = doc.CreateDocumentFragment();
xmlDocFrag.InnerXml = addxml;
XmlElement parentEle = doc.DocumentElement;
parentEle.AppendChild(xmlDocFrag);

它返回的值类似于

<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
    <Body>
        <readContract xmlns="http://implementation.company.schema.reference">
            <ContactNumbers>10158</ContactNumbers>
            <productGroups>0085</productGroups>
            <productGroups>0093</productGroups>
            <indicationBalanceInfo>false</indicationBalanceInfo>
            <indicationBlocked>true</indicationBlocked>
        </readContract>
    </Body>
    <productGroups xmlns="">0093</productGroups>
</Envelope>

我是 C# 代码的新手,请帮助我按预期获取 XML 文档。 非常感谢您的帮助。

【问题讨论】:

  • 您能否具体指出您的输出有什么问题,即它与您要查找的内容不匹配?请不要让我们梳理您的 XML 来试图找出问题所在。
  • 它只是将新元素添加到文档的顶部节点。您需要导航到要将其添加到的节点 - 在您的情况下是 节点。
  • 使用像XmlNode titleNode = doc.SelectSingleNode("//Envelope/Body/readContract");这样的XPath查询

标签: c# xml hp-uft


【解决方案1】:

当你这样做时:

XmlElement parentEle = doc.DocumentElement;
parentEle.AppendChild(xmlDocFrag);

您将节点附加到文档的根目录。您可能想要选择项目应该附加到的实际readContract 节点。举个例子:

XmlNode newNode = doc.CreateNode(XmlNodeType.Element, "productGroup", "");
newNode.InnerText = "something";

XmlNode readContractNode = doc["Envelope"]["Body"]["readContract"];
XmlElement groups = readContractNode["productGroups"];
readContractNode.InsertAfter(newNode, groups);

当然,您可能想要处理已经有多个子 productGroup 元素的情况,但想法是一样的。

【讨论】:

    【解决方案2】:

    看起来是命名空间导致了问题。这对我有用:

    XmlDocument doc = new XmlDocument();
    doc.LoadXml(File.ReadAllText("XMLFile1.xml"));
    XmlNamespaceManager ns = new XmlNamespaceManager(doc.NameTable);
    ns.AddNamespace("ns1", "http://schemas.xmlsoap.org/soap/envelope/");
    ns.AddNamespace("ns2", "http://implementation.company.schema.reference");
    var rootNode = doc.SelectSingleNode("//ns1:Envelope", ns);
    var readContractNode = rootNode.FirstChild.FirstChild;
    var newNode = doc.CreateNode(XmlNodeType.Element, "productGroups", "http://implementation.company.schema.reference");
    newNode.InnerText = "0093";
    readContractNode.InsertAfter(newNode, readContractNode.SelectSingleNode("//ns2:productGroups", ns));
    

    或者,如果您不喜欢像我这样的命名空间,您可以尝试更多“蛮力”的方法:

    XmlDocument doc = new XmlDocument();
    doc.LoadXml(File.ReadAllText("XMLFile1.xml"));
    var newNode = doc.CreateNode(XmlNodeType.Element, "productGroups", "http://implementation.company.schema.reference");
    newNode.InnerText = "0093";
    doc.FirstChild.FirstChild.FirstChild.InsertAfter(newNode, doc.FirstChild.FirstChild.FirstChild.FirstChild.NextSibling);
    

    它可以被优化,但我认为它有助于指出根本原因是文档中不同的命名空间。

    【讨论】:

      【解决方案3】:

      您可能想要使用 XmlNode.InsertAfter 方法

      public virtual XmlNode InsertAfter(
          XmlNode newChild,
          XmlNode refChild
      )
      

      在哪里

      newChild = The XmlNode to insert

      refChild = The XmlNode that is the reference node. The newNode is placed after the refNode

      请查看 this 链接以获取信息。

      并检查 this 链接以及 SO 上的答案。

      附言
      在发布新问题之前,请务必检查其他答案。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-11-28
        • 1970-01-01
        • 2022-08-18
        • 1970-01-01
        相关资源
        最近更新 更多