尝试在C#中使用XmlDocument的'InsertBefore'时发生异常

时间:2010-11-09 10:56:35

标签: c# xml


         我试图在另一个xmlnode之前插入一个xml节点,我有一个例外,说“参考节点不是这个节点的子节点。”

这是我的初始xml:

<?xml version="1.0" encoding="utf-8" ?>
<Details xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <sampleData>
    <otherNodes></otherNodes>
  </sampleData>
</Details>

我希望将以下xml数据(b:dataTobeInserted1,b:dataTobeInserted2和b:dataTobeInserted3)作为详细信息的子项但在 sampleData 之前插入。

Details1.xml

<?xml version="1.0" encoding="utf-8" ?>
<DataInserted1 xmlns:b="http://example.com/data">
  <b:dataTobeInserted1>
    <b:otherDetails1></b:otherDetails1>
  </b:dataTobeInserted1>
</DataInserted1>

Details2.xml

<?xml version="1.0" encoding="utf-8" ?>
<DataInserted2 xmlns:b="http://example.com/data">
  <b:dataTobeInserted2>
    <b:otherDetails2></b:otherDetails2>
  </b:dataTobeInserted2>
</DataInserted2>

Details3.xml

<?xml version="1.0" encoding="utf-8" ?>
<DataInserted3 xmlns:b="http://example.com/data">
  <b:dataTobeInserted3>
    <b:otherDetails3></b:otherDetails3>
  </b:dataTobeInserted3>
</DataInserted3>

我希望我的输出为

<?xml version="1.0" encoding="utf-8" ?>
<Details xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"  xmlns:b="http://example.com/data">
  <b:dataTobeInserted1>
    <b:otherDetails1></b:otherDetails1>
  </b:dataTobeInserted1>
  <b:dataTobeInserted2>
    <b:otherDetails2></b:otherDetails2>
  </b:dataTobeInserted2>
  <b:dataTobeInserted3>
    <b:otherDetails3></b:otherDetails3>
  </b:dataTobeInserted3>
  <sampleData>
    <otherNodes></otherNodes>
  </sampleData>
</Details>

这是我为实现所需输出而采取的措施。

    XmlDocument xmldoc = new XmlDocument();
    xmldoc.Load(@"..\..\initial-Doc.xml");

    xmldoc.DocumentElement.SetAttribute("xmlns:b", "http://example.com/data");


        XmlDocument detail1 = new XmlDocument();
        detail1.Load(@"..\..\DataToBeInserted1.xml");
        XmlNode detail1Node = xmldoc.ImportNode(detail1.DocumentElement, true);

        XmlDocument detail2 = new XmlDocument();
        detail2.Load(@"..\..\DataToBeInserted2.xml");
        XmlNode detail2Node = xmldoc.ImportNode(detail2.DocumentElement, true);

        XmlDocument detail3 = new XmlDocument();
        detail3.Load(@"..\..\DataToBeInserted3.xml");
        XmlNode detail3Node = xmldoc.ImportNode(detail3.DocumentElement, true);

    xmldoc.InsertBefore(detail1Node, xmldoc.DocumentElement.FirstChild);
    xmldoc.InsertBefore(detail2Node, xmldoc.DocumentElement.FirstChild);
    xmldoc.InsertBefore(detail3Node, xmldoc.DocumentElement.FirstChild);

    xmldoc.Save(@"..\..\initial-Doc-new.xml");

新命名空间是否导致问题?请告诉我哪里出错了。

由于 亚历

3 个答案:

答案 0 :(得分:21)

在我看来问题就是异常所说的:“引用节点不是该节点的子节点。”唯一棘手的部分是找出他们所指的节点。 : - )

此处“此节点”表示您正在调用InsertBefore()方法的XmlNode,“参考节点”表示{{的第二个参数3}}()。所以在以下行中:

xmldoc.InsertBefore(detail1Node, xmldoc.DocumentElement.FirstChild);

它说xmldoc.DocumentElement.FirstChild不是xmldoc的孩子。

这是真的。 xmldoc.DocumentElement.FirstChildxmldoc.DocumentElement的孩子。

因此,如果您将该行更改为以下内容,则应修复该问题:

xmldoc.DocumentElement.InsertBefore(detail1Node, xmldoc.DocumentElement.FirstChild);

答案 1 :(得分:1)

您需要制作节点的副本,因为您无法将xml节点从一个文档添加到另一个文档。

认为使用CloneNode()方法复制节点应该足够了,但如果失败,您可以从节点InnerXml或{{1}创建一个新节点} property。

答案 2 :(得分:0)

您需要使用XmlDocument类的ImportNode方法:

XmlNode importedDetailsNode = xmldoc.ImportNode(detail3.DocumentElement, true);
xmldoc.InsertBefore(importedDetailsNode , xmldoc.DocumentElement.FirstChild);

有关MSDN文档,请参阅here