【问题标题】:How to merge one specific tag into one XML using c#?如何使用 c# 将一个特定标签合并到一个 XML 中?
【发布时间】:2020-08-25 06:36:55
【问题描述】:

我有两个 XMLs'

XML1:

'<?xml version="1.0" encoding="utf-8"?>
    <Data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
         <Filename>1234</Filename>
             <Sequence Type="FRONT">
                <Object>
                    <Value>3421</Value>
                    <Value>John</Value>
                </Object>
             </Sequence>
      </Data>'

XML2:

 '<?xml version="1.0" encoding="utf-8"?>
    <Data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
         <Filename>1234</Filename>
             <Sequence Type="FRONT">
                <Object>
                    <Value>1234</Value>
                    <Value>SAM</Value>
                </Object>
             </Sequence>
      </Data>'

我想要下面的输出

 '<?xml version="1.0" encoding="utf-8"?>
    <Data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
         <Filename>1234</Filename>
             <Sequence Type="FRONT">
                <Object>
                    <Value>3421</Value>
                    <Value>John</Value>
                </Object>
                <Object>
                    <Value>1234</Value>
                    <Value>SAM</Value>
                </Object>
             </Sequence>
      </Data>'

即我想使用 C# 代码将 Object 标记从 XML2 合并到 XML1。

有人可以帮我吗?

【问题讨论】:

    标签: c# xml


    【解决方案1】:

    您可以使用 XPath 选择您需要的节点,然后只需使用 .NET xml using System.Xml

    更多信息请查看https://www.w3schools.com/xml/xpath_intro.asp

    加载 Xml 文档

    我将您提供的两个示例 xml 文件保存为单独的文件并像这样导入它们 XmlDocument doc1 = new XmlDocument(); XmlDocument doc2 = new XmlDocument();

        using (var sw = new StreamReader("xml1.xml"))
        {
            var text = sw.ReadToEnd();
            doc1.LoadXml(text);
        }
    
        using (var sw = new StreamReader("xml2.xml"))
        {
            var text = sw.ReadToEnd();
            doc2.LoadXml(text);
        }
    

    使用 XPATH 选择节点

    我们将获取所有名为“object”的元素并将它们添加到另一个 xml 的“sequence”元素的子元素中。因此,我们选择一个文档的“序列”元素和另一个文档的“对象”元素。

        var sequenceNodes = doc1.SelectSingleNode("/Data/Sequence");
        var objectNodes = doc2.SelectNodes("/Data/Sequence/Object");
    

    将节点合并到一个文档中

    然后我们获取每个“对象”元素,将其导入到另一个文档上下文中,并将其附加到“序列”节点下

        foreach (XmlNode node in objectNodes)
        {
            XmlNode importedNode = doc1.ImportNode(node, true);
            sequenceNodes.AppendChild(importedNode);
        }
    

    输出文件

        using (var stringWriter = new StringWriter())
        using (var xmlTextWriter = XmlWriter.Create(stringWriter))
        {
            doc1.WriteTo(xmlTextWriter);
            xmlTextWriter.Flush();
            File.AppendAllText("out.xml", stringWriter.GetStringBuilder().ToString());
        }
    

    输出文件如下所示:

    【讨论】:

    • 没问题;)如果对您有帮助,您可以接受它作为答案;)
    【解决方案2】:

    请看一下这个解决方案: what-is-the-fastest-way-to-combine-two-xml-files-into-one

    使用 Union 方法似乎是您所寻求的。

    【讨论】:

      【解决方案3】:

      运行 XSLT 转换:

      <xsl:template name="merge">
         <Data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
               xmlns:xsd="http://www.w3.org/2001/XMLSchema">
               <Filename>1234</Filename>
               <Sequence Type="FRONT">
                      <xsl:copy-of select="document('a.xml')//Object"/>
                      <xsl:copy-of select="document('b.xml')//Object"/>
               </Sequence>
         </Data>
      </xsl:template>  
      

      【讨论】:

        【解决方案4】:

        尝试以下 linq,它将所有具有相同值的文件名连接起来。

        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Text;
        using System.Xml;
        using System.Xml.Linq;
        
        namespace ConsoleApplication166
        {
            class Program
            {
                const string FILENAME1 = @"c:\temp\test.xml";
                const string FILENAME2 = @"c:\temp\test1.xml";
                static void Main(string[] args)
                {
                    XDocument doc1 = XDocument.Load(FILENAME1);
                    XNamespace ns1 = doc1.Root.GetDefaultNamespace();
                    XDocument doc2 = XDocument.Load(FILENAME2);
                    XNamespace ns2 = doc2.Root.GetDefaultNamespace();
        
                    var joins= from d1 in doc1.Descendants(ns1 + "Data")
                               join d2 in doc2.Descendants(ns2 + "Data")
                               on (string)d1.Element(ns1 + "Filename") equals (string)d2.Element(ns2 + "Filename")
                               select new { d1 = d1, d2 = d2};
        
                    foreach (var join in joins)
                    {
                        XElement d2Object = join.d2.Descendants("Object").FirstOrDefault(); 
                        join.d1.Descendants("Sequence").FirstOrDefault().Add(XElement.Parse(d2Object.ToString()));
                    }
        
        
                }
            }
         
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-12-22
          • 2023-01-18
          • 1970-01-01
          • 2014-07-09
          • 1970-01-01
          • 2018-10-10
          • 1970-01-01
          相关资源
          最近更新 更多