Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何用C语言合并2个XML文件_C#_Xml_Linq - Fatal编程技术网

C# 如何用C语言合并2个XML文件

C# 如何用C语言合并2个XML文件,c#,xml,linq,C#,Xml,Linq,我有两个XML文件,我想将这两个文件合并为一个。 但是怎么做呢?我试了很多,但都没用。 正如您所看到的,如果第二个属性的文本来自第一个XML,那么合并的XML将保留第二个属性的文本。 其次,元素必须按第一个属性的Id/Name/whatevername排序。 第三,如果XML 2中不存在节点,则必须在与XML 1相同的位置创建它 这里显示的XML文件只是整个XML的一个片段,还有更多的属性名称 我怎样才能用C来做这个 XML 1 XML 2 <APPLICATION> <

我有两个XML文件,我想将这两个文件合并为一个。 但是怎么做呢?我试了很多,但都没用。 正如您所看到的,如果第二个属性的文本来自第一个XML,那么合并的XML将保留第二个属性的文本。 其次,元素必须按第一个属性的Id/Name/whatevername排序。 第三,如果XML 2中不存在节点,则必须在与XML 1相同的位置创建它

这里显示的XML文件只是整个XML的一个片段,还有更多的属性名称

我怎样才能用C来做这个

XML 1

XML 2

<APPLICATION>
    <AC>
            <CLASS Name="Hello1" Capt="dodo1"/>
            <CLASS Name="Hello2" Capt="dodo2"/>
            <CLASS Name="Hello3" Capt="dodo3"/>
            <CLASS Name="Hello9" Capt="dodo9"/>
    </AC>
    <CARS Wheel="Fore" Default="45x255xZ"/>
    <CARS Wheel="BACK" Default="45x255xZ"/>
    <CARS Wheel="SPARE" Default="45x255xZ"/>
    <BO>
            <ITEM Id="1" DefaultValue="namename1"/>
            <ITEM Id="3" DefaultValue=""/>
            <ITEM Id="9" DefaultValue="name11"/>
            <ITEM Id="10" DefaultValue="name12">
                    <VAL>
                            <REASON Id="Job1" SecondOne="Hallo"/>
                    </VAL>
            </ITEM>
    </BO>
合并后的XML应如下所示:

<APPLICATION>
    <AC>
            <CLASS Name="Hello1" Capt="dodo1"/>
            <CLASS Name="Hello2" Capt="dodo2"/>
            <CLASS Name="Hello3" Capt="dodo3"/>
            <CLASS Name="Hello5" Capt=""/>
            <CLASS Name="Hello8" Capt=""/>
            <CLASS Name="Hello9" Capt="dodo9"/>
    </AC>
    <CARS Wheel="Fore" Default="45x255xZ"/>
    <CARS Wheel="BACK" Default="45x255xZ"/>
    <CARS Wheel="SPARE" Default="45x255xZ"/>
    <BO>
            <ITEM Id="1" DefaultValue="namename1"/>
            <ITEM Id="3" DefaultValue=""/>
            <ITEM Id="9" DefaultValue="name11"/>
            <ITEM Id="10" DefaultValue="name12">
                    <VAL>
                            <REASON Id="Job1" SecondOne="Hallo"/>
                    </VAL>
            </ITEM>
            <ITEM Id="11" DefaultValue=""/>
            <ITEM Id="12" DefaultValue="">
                    <VAL>
                            <REASON Id="Job1" SecondOne=""/>
                    </VAL>
            </ITEM>
    </BO>
    <POP Id="Green" Value=""/>
    <POP Id="Blue" Value=""/>
所有答案都是Thanx,但我仍然有一个问题,我不知道标记名是什么,所以我不能硬编码标记

我只想给你举个例子看看它是什么样子。但下一次我获取XML文件时,上面的标记可能会完全不同。这就是问题所在。所以我不能说新的XElementBO,boChildren,因为下次这个标签不存在了


或者我不能硬编码这个==>var cars=xDocuments.SelectManyx=>x.Root.ElementsCARS.Merge;因为下一次我获取XML文件时,CARS不再存在。

您可以使用XmlDocument类。 检查此链接:
我建议您不要使用C。尽量使用XSLT,它主要用于转换XML


如果您确实想使用C,那么请使用新的C 3.5/4 XDocument。它有很好的基于LINQ的语法,这使得它更容易使用。

我认为您可以使用LINQ to XML来实现这一点。为每个段AC、BO、CARS、POP创建单独的查询,然后将它们合并到一个新文档中

下面是一个小片段,让您开始学习:

using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;

namespace XML_Merge {
    class Program {
        static void Main(string[] args) {

            // load two xdocs
            var x1 = XDocument.Load("x1.xml");
            var x2 = XDocument.Load("x2.xml");

            // select the CLASS nodes from each
            var c1 = x1.Descendants("AC").First().Descendants("CLASS");
            var c2 = x2.Descendants("AC").First().Descendants("CLASS");

            // this one gives the distinct union of the two, you can put that into the result xdoc.
            var cComb =
                c1
                .Union(c2)
                .Distinct(new ClassComparer()) // this uses the IEqualityComparer from below
                .OrderBy(c => c.Attribute("Name").Value);
        }
    }

    // This is required for Union to work. (Also Intersect etc)
    class ClassComparer : IEqualityComparer<XElement> {
        public bool Equals(XElement x, XElement y) { return x.Attribute("Name").Value == y.Attribute("Name").Value; }
        public int GetHashCode(XElement obj) { return obj.Attribute("Name").Value.GetHashCode(); }
    }
}
只需对源文档中的其他节点重复此操作,然后将其全部放在一起

祝你好运


Gert Jan

你可以有这样的东西:

class APPLICATION
{
    public APPLICATION()
    {
        this.Classes = new List<CLASS>();
        this.Cars = new List<CARS>();
        this.Items = new List<ITEM>();
        this.Pops = new List<POP>();
    }

    public List<CLASS> Classes { get; set; }

    public List<CARS> Cars { get; set; }

    public List<ITEM> Items { get; set; }

    public List<POP> Pops { get; set; }

    public override string ToString()
    {
        string toString = string.Empty;
        using (MemoryStream stream = new MemoryStream())
        {
            using (XmlTextWriter writer = new XmlTextWriter(stream, Encoding.UTF8))
            {
                writer.Formatting = Formatting.Indented;
                writer.Indentation = 5;
                writer.WriteStartDocument();
                    writer.WriteStartElement("APPLICATION");
                        writer.WriteStartElement("AC");
                        if (this.Classes != null && Classes.Count > 0)
                        {
                            foreach (CLASS c in Classes)
                            {
                                writer.WriteStartElement("CLASS");
                                    writer.WriteAttributeString("Name", c.Name);
                                    writer.WriteAttributeString("Capt", c.Capt);
                                writer.WriteEndElement(); //CLASS
                            }
                        }
                        writer.WriteEndElement(); //AC

                        if (this.Cars != null && Cars.Count > 0)
                        {
                            foreach (CARS c in Cars)
                            {
                                writer.WriteStartElement("CARS");
                                    writer.WriteAttributeString("Wheel", c.Wheel);
                                    writer.WriteAttributeString("Default", c.Default);
                                writer.WriteEndElement(); //CARS
                            }
                        }

                        writer.WriteStartElement("BO");
                        if (this.Items != null && Items.Count > 0)
                        {
                            foreach (ITEM c in Items)
                            {
                                writer.WriteStartElement("ITEM");
                                    writer.WriteAttributeString("Id", c.Id);
                                    writer.WriteAttributeString("DefaultValue", c.DefaultValue);
                                    if (c.Reason != null)
                                    {
                                        writer.WriteStartElement("VAL");
                                            writer.WriteStartElement("REASON");
                                                writer.WriteAttributeString("Id", c.Reason.Id);
                                                writer.WriteAttributeString("SecondOne", c.Reason.SecondOne);
                                            writer.WriteEndElement(); //ITEM
                                        writer.WriteEndElement(); //VAL
                                    }
                                writer.WriteEndElement(); //ITEM
                            }
                        }
                        writer.WriteEndElement(); //BO
                    writer.WriteEndElement(); //APPLICATION
                writer.WriteEndDocument();

                writer.Flush();
                stream.Position = 0;

                XmlTextReader reader = new XmlTextReader(stream);

                reader.MoveToContent();
                toString = reader.ReadOuterXml();

                writer.Close();
                stream.Close();
            }
        }

        return toString;
    }
}

public class REASON
{
    public REASON()
    {
        Id = string.Empty;
        SecondOne = string.Empty;
    }

    public string Id { get; set; }
    public string SecondOne { get; set; }
}

public class ITEM
{
    public ITEM()
    {
        Id = string.Empty;
        DefaultValue = string.Empty;
    }

    public string Id { get; set; }
    public string DefaultValue { get; set; }
    public REASON Reason { get; set; }
}

public class CARS
{
    public CARS()
    {
        Wheel = string.Empty;
        Default = string.Empty;
    }

    public string Wheel { get; set; }
    public string Default { get; set; }
}

public class CLASS
{
    public CLASS()
    {
        Name = string.Empty;
        Capt = string.Empty;
    }

    public string Name { get; set; }
    public string Capt { get; set; }
}

public class POP
{
    public POP()
    {
        Id = string.Empty;
        Value = string.Empty;
    }

    public string Id { get; set; }
    public string Value { get; set; }
}
APPLICATION application = new APPLICATION();
application.Classes = ... //Populate this with classes read from xml 1 and 2.
application.Cars = ... //Populate this with cars read from xml 1 and 2.
application.Items = ... //Populate this with items read from xml 1 and 2.
application.Pops = ... //Populate this with pops read from xml 1 and 2.
string yourXmlString = application.ToString();

这里有一些代码让你开始。但是,对于如何从原始元素生成合并元素,您有一些非常具体的要求。您必须在扩展方法中实现这一点:

var xDocuments = new[] { XDocument.Parse(xml1), XDocument.Parse(xml2) };

var acChildren = xDocuments.SelectMany(x => x.Root.Elements("AC"))
  .SelectMany(x => x.Elements()).Merge();
var cars = xDocuments.SelectMany(x => x.Root.Elements("CARS")).Merge();
var boChildren = xDocuments.SelectMany(x => x.Root.Elements("BO"))
  .SelectMany(x => x.Elements()).Merge();
var pops = xDocuments.SelectMany(x => x.Root.Elements("POP")).Merge();

var mergedXDocument = new XDocument(
  new XElement("APPLICATION",
    new XElement("AC", acChildren),
    cars,
    new XElement("BO", boChildren),
    pops
  )
);
public static class Extensions {

  public static IEnumerable<XElement> Merge(this IEnumerable<XElement> xElements) {
    // Implement the requirement:
    // "the merged XML has left the text from the second attribute if it came from
    // the first XML"
  }

}
以下是扩展方法的模板:

var xDocuments = new[] { XDocument.Parse(xml1), XDocument.Parse(xml2) };

var acChildren = xDocuments.SelectMany(x => x.Root.Elements("AC"))
  .SelectMany(x => x.Elements()).Merge();
var cars = xDocuments.SelectMany(x => x.Root.Elements("CARS")).Merge();
var boChildren = xDocuments.SelectMany(x => x.Root.Elements("BO"))
  .SelectMany(x => x.Elements()).Merge();
var pops = xDocuments.SelectMany(x => x.Root.Elements("POP")).Merge();

var mergedXDocument = new XDocument(
  new XElement("APPLICATION",
    new XElement("AC", acChildren),
    cars,
    new XElement("BO", boChildren),
    pops
  )
);
public static class Extensions {

  public static IEnumerable<XElement> Merge(this IEnumerable<XElement> xElements) {
    // Implement the requirement:
    // "the merged XML has left the text from the second attribute if it came from
    // the first XML"
  }

}