2010-11-09 78 views
9


我試圖在另一個xmlnode之前插入一個xml節點,並且出現一個異常說「引用節點不是此節點的子節點」。嘗試在C#中使用XmlDocument的'InsertBefore'時發生異常

這是我最初的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 DATAS(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"); 

新命名空間是否導致問題?請告訴我我錯了哪裏。

感謝 亞歷克斯

回答

21

在我看來,問題正是這個例外所說的:「參考節點不是這個節點的子節點。」唯一棘手的部分是弄清楚他們指的是哪個節點。 :-)

這裏「這個節點」指其InsertBefore()方法你打電話,和「參考節點」的XmlNode的意思的第二個參數InsertBefore()。因此,在下面一行:

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

它說xmldoc.DocumentElement.FirstChild不是xmldoc一個孩子。

這是真的。 xmldoc.DocumentElement.FirstChildxmldoc.DocumentElement的小孩。如果更改了該行對以下

所以,這個問題應該是固定的:

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

感謝隊友它的工作,非常感謝我的問題很好的解釋。感謝:) – wizzardz 2010-11-09 11:35:23

+0

@亞歷克斯:很高興能爲您服務! – LarsH 2010-11-09 17:23:48

+0

這也解決了我的問題。我希望這個XML文檔更清晰一點 – 2016-05-13 12:18:14

1

你需要讓節點的副本,因爲你不能從一個文檔添加一個XML節點到另一個節點。

認爲複製使用CloneNode()方法應該是足夠的節點,但如果失敗,你可以從節點InnerXmlOuterXml屬性創建一個新的節點。

+0

如果你看一看到輸出XML,你可以看到有添加到一個新的命名空間。這是造成問題嗎? – wizzardz 2010-11-09 11:28:15

0

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

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

看到here的MSDN文檔。

+0

做了,但它仍然在工作 – wizzardz 2010-11-09 11:18:45

相關問題