如果我有两个xml1和xml2字符串,它们都以相同的格式表示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 :(得分:44)
最简单的方法是使用LINQ to XML。您可以根据需要使用Union或Concat。
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"));
答案 1 :(得分:8)
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文档,例如一个空的。
答案 2 :(得分:4)
这是合并xml文件的最快,最干净的方法。
XElement xFileRoot = XElement.Load(file1.xml);
XElement xFileChild = XElement.Load(file2.xml);
xFileRoot.Add(xFileChild);
xFileRoot.Save(file1.xml);
答案 3 :(得分:2)
如果你能保证这种格式,你可以通过字符串操作来组合它们:
这应该是最快的方法,因为不需要解析。
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);
那就是说我总是喜欢快速通道的安全方式。
答案 4 :(得分:2)
如果要使用XmlDocument,请尝试使用
var lNode = lDoc1.ImportNode(lDoc2.DocumentElement.FirstChild, true);
lDoc1.DocumentElement.AppendChild(lNode);
答案 5 :(得分:1)
您有两个基本选项:
解析xml,合并数据结构,序列化回xml。
如果您知道结构,请使用一些基本的字符串操作来破解它。例如,在上面的示例中,您可以将两个xml块中的所有节点内部放在一个allnodes块中并完成。
答案 6 :(得分:1)
var doc = XDocument.Load(“file1.xml”);
var doc1 = XDocument.Load(“file2.xml”);
doc.Root.Add(doc2.Root.Elements());
答案 7 :(得分:1)
对我来说是最好的解决方案,基于Jose Basilio的回答,略有修改,
var combinedUnique = xml1.Descendants()
.Union(xml2.Descendants());
combinedUnique.First().Save(#fullName)
答案 8 :(得分:0)
如果我这样做(使用C#),我会创建一个类,我可以将此反序列化为(您可以使用xsd.exe执行此操作),然后遍历代表第一个的对象中的所有节点一段XML并将它们“添加”到表示第二个XML的对象的AllNodes属性。
然后将第二个类序列化为XML,它应该看起来像你的第三个例子。
答案 9 :(得分: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上看到它。
答案 10 :(得分:0)
在我的情况下主要解决方案效果不佳,不同之处在于,当我拿一个元素并尝试与第一个元素合并时,我有一个数千个文件的List我得到OutOfMemory例外,我添加了一个空模板和空行(在本例中为NodeA)来解决内存的奇怪问题并顺利运行。
我将文档保存在其他进程中
XDocument xmlDocTemplate = GetXMLTemplate(); -- create an empty document with the same root and empty row element (NodeA), everything will be merge here.
List<XElement> lstxElements = GetMyBunchOfXML();
foreach (var xmlElement lstxElements)
{
xmlDocTemplate
.Root
.Descendants("NodeA")
.LastOrDefault()
.AddAfterSelf(xmlElement.Descendants("NodeA"));
}