C# 将两个xml文件合并为一个xml文件的最快方法是什么
如果我有两个字符串xml1和xml2,它们都以相同的格式表示xml。把这些结合在一起最快的方法是什么?格式并不重要,但我只想知道如何摆脱或删除 xml1:C# 将两个xml文件合并为一个xml文件的最快方法是什么,c#,xml,C#,Xml,如果我有两个字符串xml1和xml2,它们都以相同的格式表示xml。把这些结合在一起最快的方法是什么?格式并不重要,但我只想知道如何摆脱或删除 xml1: <?xml version="1.0" encoding="utf-8"?> <AllNodes> <NodeA> <NodeB>test1</NodeB> <NodeB>test2</NodeB> </NodeA&g
<?xml version="1.0" encoding="utf-8"?>
<AllNodes>
<NodeA>
<NodeB>test1</NodeB>
<NodeB>test2</NodeB>
</NodeA>
</AllNodes>
测试1
测试2
xm2:
测试6
测试7
测试99
测试23
有这样的东西:
<?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>
测试1
测试2
测试6
测试7
测试99
测试23
如果我正在这样做(使用C#),我会创建一个类,我可以将这个XML反序列化到该类(可以使用xsd.exe来执行此操作),然后循环遍历对象中表示第一段XML的所有节点,并将它们“添加”到表示第二段XML的对象的AllNodes属性中
然后将第二个类序列化回XML,它应该与您的第三个示例类似。您有两个基本选项:
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文档,例如空文档。如果可以保证此格式,则可以通过执行字符串操作将其组合:
- 读取第一个文件,在“”之前保留所有内容
- 读取第二个文件,删除零件直至“”
- 把这些弦组合起来
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);
const string relevantag=“AllNodes”;
字符串xml1=File.ReadAllText(xmlFile1);
xml1=xml1.Substring(0,xml.LastIndexOf(“”);
字符串xml2=File.ReadAllText(xmlFile2);
xml2=xml2.Substring(xml.IndexOf(“”+“”)长度,xml1.Length);
writealText(xmlFileCombined,xm1+xml2);
也就是说,与快速方法相比,我更喜欢安全方法。最简单的方法是使用LINQ to XML。根据您的需要,您可以使用或
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"));
因为你要的是最快的: 如果(且仅当)xml结构始终一致:(这是伪代码)
string xml1=//以某种方式获取xml1
字符串xml2=//以某种方式获取xml2
xml1=替换(xml1,“,”);
xml1=替换(xml1,“,”);
xml1=替换(xml1,“,”);
xml2=替换(xml2,“,“\n”+xml1);
这是一个巨大的黑客,但速度很快。当您的同事找到它时,希望在DailyWF上看到它。如果您想使用XML文档,请尝试以下方法
var lNode = lDoc1.ImportNode(lDoc2.DocumentElement.FirstChild, true);
lDoc1.DocumentElement.AppendChild(lNode);
这是合并xml文件的最快、最干净的方法
XElement xFileRoot = XElement.Load(file1.xml);
XElement xFileChild = XElement.Load(file2.xml);
xFileRoot.Add(xFileChild);
xFileRoot.Save(file1.xml);
我的最佳解决方案,基于Jose Basilio的回答,稍加修改
var combinedUnique = xml1.Descendants()
.Union(xml2.Descendants());
combinedUnique.First().Save(#fullName)
在我的例子中,主要的解决方案没有很好地工作,不同的是,当我获取一个元素并尝试与从内存中获取的第一个元素合并时,我有一个包含数千个文件的列表。例外,我添加了一个空模板,其中包含一个空行(本例中为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"));
}
XDocument xmlDocTemplate=GetXMLTemplate();--创建一个具有相同根元素和空行元素(NodeA)的空文档,所有内容都将在此处合并。
List lstxElements=GetMyBunchOfXML();
foreach(var xmlElement lstxElements)
{
xmlDocTemplate
.根
.后代(“NodeA”)
.LastOrDefault()
.AddAfterSelf(xmlement.substands(“NodeA”);
}
非常感谢您。您的解决方案看起来不错,但您知道我如何将该模式应用于xml文档吗?例如,的公认答案显示了如何在.NET中实现这一点。另一方面,如果您对XSLT一无所知,它可能不是您理想的解决方案。我不知道与本线程中建议的其他方法相比,它的性能如何。问题是我有两个字符串,而不是两个xml文件。这两个字符串表示从另一个站点发送的xml元素。有什么方法可以将我的字符串转换为XElement或类似的东西吗?这样我就可以遍历它的元素了?要将字符串转换为XElement,可以使用XElement.Parse(yourstring)也可以使用XDocument.Parse(yourstring)将字符串转换为XDocument。Jose Basilio的答案很好,但不完整,它将创建一个包含2个“AllNodes”元素的XElement IEnumerator。更准确的答案是(如果不存在重复的问题):xml1.substands(“NodeA”).LastOrDefault().AddAfterSelf(xml2.substands(“NodeA”);xml1.Save()代码>@Vlax这是一个令人伤心的完成,你能告诉我如何将此文件保存为新文件吗?比如,如果xml2被xml1替换,我需要将结果另存为xml3,那么是否可能?出于我自己的需要。还有一个.thankyou@user3510339代码,不过它只保存了第一个XML文件的内容。这是保留还是删除重复项?最简单也是最好的方法。
XElement xFileRoot = XElement.Load(file1.xml);
XElement xFileChild = XElement.Load(file2.xml);
xFileRoot.Add(xFileChild);
xFileRoot.Save(file1.xml);
var combinedUnique = xml1.Descendants()
.Union(xml2.Descendants());
combinedUnique.First().Save(#fullName)
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"));
}