簡體   English   中英

在C#中合並兩個XML文件,其中一個是不符合的

[英]Merge two XML files, one of which is non-conformant, in C#

我有兩個XML文件需要合並到一個文件中。 當我嘗試合並它們時,我得到一個錯誤,說它們中的一個不符合。

違規的XML文件看起來像:

<letter>
    <to>
        <participant>
            <name>Joe Bethersonton</name>
            <PostalAddress>Apartment 23R, 11454 Pruter Street</PostalAddress>
            <Town>Fargo, North Dakota, USA</Town>
            <ZipCode>50504</ZipCode>
        </participant>
    </to>
    <from>
        <participant>
            <name>Jon Doe</name>
            <PostalAddress>52 Generic Street</PostalAddress>
            <Town>Romford, Essex, UK</Town>
            <ZipCode>RM11 2TH</ZipCode>
        </participant>
    </from>
</letter>

我正在嘗試使用以下代碼段合並這兩個文件:

try
{
    Dataset ds = new DataSet();
    Dataset ds2 = new DataSet();
    XmlTextReader reader1 = new XmlTextReader("C:\\File1.xml");
    XmlTextReader reader2 = new XmlTextReader("C:\\File2.xml");
    ds.ReadXml(reader1);
    ds2.ReadXml(reader2);
    ds.Merge(ds2);
}
catch(System.Exception ex)
{
    Console.WriteLine(ex.Message);
}

這會出現以下錯誤:

同一個表'參與者'不能是兩個嵌套關系中的子表。

這兩個XML文件都以UTF-16編碼,這使得它們通過簡單的文本讀寫很難組合。

我需要的最終結果是一個XML文件,其中第一個XML文件的內容后跟第二個XML文件的內容,整個批次周圍有一個標記,頂部有一個標題。

有任何想法嗎?

謝謝,Rik

在我看來,你提供的XML就好了。 我建議你使用以下代碼,根本不使用數據集類:

XDocument doc1 = XDocument.Load("C:\\File1.xml");
XDocument doc2 = XDocument.Load("C:\\File2.xml");
var result = new XDocument(new XElement("Root", doc1.Root, doc2.Root));

result將包含一個XML文檔,其中“Root”作為根標記,然后是文件1的內容,后跟文件2的內容。

更新:
如果需要使用XmlDocument ,可以使用以下代碼:

XmlDocument doc1 = new XmlDocument();
XmlDocument doc2 = new XmlDocument();
doc1.Load("C:\\File1.xml");
doc2.Load("C:\\File2.xml");
XmlDocument result = new XmlDocument();
result.AppendChild(result.CreateElement("Root"));
result.DocumentElement.AppendChild(result.ImportNode(doc1.DocumentElement, true));
result.DocumentElement.AppendChild(result.ImportNode(doc2.DocumentElement, true));

我懷疑解決方案是提供架構。 DataSet.Merge不知道如何處理兩組具有相同名稱的元素。 它試圖推斷一個模式,但這在這里效果不佳。

根據MSDN上的這個帖子 ,這是DataSet類的限制:

.NET 2.0(Visual Studio 2005)中的DataSet類仍然具有不支持具有相同名稱的不同嵌套表的限制。 因此,在將XML(和模式)加載到DataSet之前,必須引入XML轉換來預處理XML(和模式)。

當然,措辭的方式使它看起來像一個較新的版本可能已經解決了這個問題。 不幸的是,情況可能並非如此,因為最初的答案是在2005年發布的。

這篇知識庫文章似乎表明這種行為是“按設計”的,雖然情況略有不同。

此線程還給出了更好地解釋為什么會發生這種行為的原因:

當ADO將XML讀入DataSet時,它會創建DataTables以包含它遇到的每種類型的元素。 每個表都由其名稱唯一標識。 您不能有兩個名為“PayList”的不同表。

此外,給定的表可以包含任意數量的父表,但只能嵌套其父關系中的一個 - 否則,給定的記錄將多次寫入XML,作為其每個父行的子項。

DataSet的ReadXml方法在讀取其輸入時可以推斷出DataSet的模式是非常方便的,但是如果XML可讀的話必須符合某些約束。 你得到的XML沒有。 因此,您有兩種選擇:可以更改XML,也可以編寫自己的方法來填充DataSet。

如果是我,我會編寫一個XSLT轉換,它將輸入XML和PayList元素轉換為MatrixPayList或NonMatrixPaylist元素。 然后我將其輸出傳遞給DataSet。

使用XmlDocumentXDocument讀入和操作XML文件是另一種可能的解決方法。 有關示例,請參閱合並兩個xml文件LINQ

我找到了一個解決方案,使用Serialization首先推斷出架構,然后序列化架構並刪除關系約束(這會讓DataSet誤以為IT已經創建了數據集。),然后將這個新架構加載到DataSet中。

這個新數據集將能夠加載您的xml文件。 這個技巧背后的更多細節: 使用WriteXML方法時的序列化問題

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM