2009-06-11 62 views
21

以最快的方式如果我有XML1和XML2兩個串都在相同的格式表示XML。將這些結合在一起的最快方法是什麼?格式不重要,但我只想知道我該如何擺脫或?什麼是兩個XML文件合併成一個

XML1:

<?xml version="1.0" encoding="utf-8"?> 
<AllNodes> 
    <NodeA> 
     <NodeB>test1</NodeB> 
     <NodeB>test2</NodeB> 
    </NodeA> 
</AllNodes> 

XM2:

<?xml version="1.0" encoding="utf-8"?> 
<AllNodes> 
    <NodeA> 
     <NodeB>test6</NodeB> 
     <NodeB>test7</NodeB> 
    </NodeA> 
    <NodeA> 
     <NodeB>test99</NodeB> 
     <NodeB>test23</NodeB> 
    </NodeA> 
</AllNodes> 

,並有這樣的事情:

<?xml version="1.0" encoding="utf-8"?> 
    <AllNodes> 
      <NodeA> 
       <NodeB>test1</NodeB> 
       <NodeB>test2</NodeB> 
      </NodeA> 
     <NodeA> 
       <NodeB>test6</NodeB> 
       <NodeB>test7</NodeB> 
      </NodeA> 
      <NodeA> 
       <NodeB>test99</NodeB> 
       <NodeB>test23</NodeB> 
      </NodeA> 
    </AllNodes> 
+0

對於自己的需要,[我趕緊寫東西合併(web.config中)的XML文件( http://pastebin.com/FzkRczZ6)。還有一個[配置文件合併工具](https://configmerger.codeplex.com/)。 – 2015-06-30 04:41:02

回答

41

要做到這一點,最簡單的方法是使用LINQ to XML。根據您的需要,您可以使用UnionConcat

var xml1 = XDocument.Load("file1.xml"); 
var xml2 = XDocument.Load("file2.xml"); 

//Combine and remove duplicates 
var combinedUnique = xml1.Descendants("AllNodes") 
          .Union(xml2.Descendants("AllNodes")); 

//Combine and keep duplicates 
var combinedWithDups = xml1.Descendants("AllNodes") 
          .Concat(xml2.Descendants("AllNodes")); 
0

如果我這樣做(用C#),我想創建一個類我可以反序列化這個XML(你可以使用xsd.exe來做到這一點),然後遍歷對象表示的所有節點第一部分XML並將它們「添加」到表示第二個XML的對象的AllNodes屬性中。

然後序列化二等背出XML,它應該看起來像你的第三個例子。

1

你有兩個基本的選擇:

  1. 解析XML,結合數據結構,序列化回XML。

  2. 如果你知道結構,使用一些基本的字符串操作來破解它。例如,在上面的示例中,您可以將兩個xml塊中的allnodes內部放入單個allnodes塊中並完成。

4

XSLT轉換可以做到這一點:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:param name="pXml1" select="''" /> 
    <xsl:param name="pXml2" select="''" /> 
    <xsl:param name="pRoot" select="'root'" /> 

    <xsl:template match="/"> 
    <xsl:variable name="vXml1" select="document($pXml1)" /> 
    <xsl:variable name="vXml2" select="document($pXml2)" /> 

    <xsl:element name="{$pRoot}"> 
     <xsl:copy-of select="$vXml1/*/*" /> 
     <xsl:copy-of select="$vXml2/*/*" /> 
    </xsl:element> 
    </xsl:template> 

</xsl:stylesheet> 

傳中,文件的名稱作爲參數,以及新的根元素的名稱。

適用於任何XML文檔,例如一個空的。

+0

非常感謝。你的解決方案看起來不錯,但是你知道如何將該模式應用於xml文檔嗎? – paradisonoir 2009-06-11 18:07:47

+0

例如,接受的答案http://stackoverflow.com/questions/529374/whats-the-property-way-to-transform-with-xsl-without-html-encoding-my-final-outp顯示如何在.NET中做它 – Tomalak 2009-06-11 18:19:36

+0

另一方面 - 如果你不知道XSLT,它可能不是你理想的解決方案。我不知道它會如何與本主題中提出的其他方式相比。 – Tomalak 2009-06-11 18:21:08

2

如果你能保證這種格式,你可以通過執行字符串操作將它們組合起來:

  • 閱讀的第一個文件,「</allnodes中>」
  • 之前把一切都讀第二個文件,刪除部分達人 「< allnodes中>」
  • 結合這些字符串。

這應該是最快的方法,因爲不需要解析。

const string RelevantTag = "AllNodes"; 

string xml1 = File.ReadAllText(xmlFile1); 
xml1 = xml1.Substring(0, xml.LastIndexOf("</" + RelevantTag + ">")); 

string xml2 = File.ReadAllText(xmlFile2); 
xml2 = xml2.Substring(xml.IndexOf("<" + RelevantTag + ">") + "<" + RelevantTag + ">".Length, xml1.Length); 

File.WriteAllText(xmlFileCombined, xm1 + xml2); 

那就是說我總是喜歡安全的方式來快速的方式。

0

既然你問了最快

如果(且僅當)的XML結構始終是一致的:(這是僞代碼)

string xml1 = //get xml1 somehow 
string xml2 = //get xml2 somehow 
xml1 = replace(xml1, "<?xml version=\"1.0\" encoding=\"utf-8\"?>", ""); 
xml1 = replace(xml1, "<allnodes>", ""); 
xml1 = replace(xml1, "</allnodes>", ""); 
xml2 = replace(xml2, "<allnodes>", "<allnodes>\n" + xml1); 

這是一個巨大的黑客但速度很快。期望您的同事在TheDailyWTF上看到它。

1

如果你想使用XmlDocument,試試這個

var lNode = lDoc1.ImportNode(lDoc2.DocumentElement.FirstChild, true); 
lDoc1.DocumentElement.AppendChild(lNode); 
0

VAR DOC = XDocument.Load( 「file1.xml」);

var doc1 = XDocument.Load(「file2.xml」);

doc.Root.Add(doc2.Root.Elements());

4

這是合併xml文件最快,最乾淨的方式。

XElement xFileRoot = XElement.Load(file1.xml); 
XElement xFileChild = XElement.Load(file2.xml); 
xFileRoot.Add(xFileChild); 
xFileRoot.Save(file1.xml); 
1

最佳的解決方案給我,基於何塞巴西利奧的回答,略作修改,

var combinedUnique = xml1.Descendants() 
    .Union(xml2.Descendants()); 
combinedUnique.First().Save(#fullName)