我有多个具有这种格式的xml流:

xml1:

<?xml version="1.0" encoding="utf-8"?>
<Node>
      <NodeA>test1</NodeA>
      <NodeB>test2</NodeB>
      <NodeC>
         <Att>test4</Att>
         <Value1>1.0</Value1>
      </NodeC>
</Node>
<Node>
      <NodeA>test1</NodeA>
      <NodeB>test7</NodeB>
      <NodeC>
         <Att>test8</Att>
         <Value1>2.0</Value1>
      </NodeC>
</Node>
...

xmlN:
<?xml version="1.0" encoding="utf-8"?>
<Node>
      <NodeA>test1</NodeA>
      <NodeB>test2</NodeB>
      <NodeC>
         <Att>test4</Att>
         <ValueN>5.0</ValueN>
      </NodeC>
</Node>
<Node>
      <NodeA>test1</NodeA>
      <NodeB>test7</NodeB>
      <NodeC>
         <Att>test8</Att>
         <ValueN>6.0</ValueN>
      </NodeC>
</Node>
<Node>
      <NodeA>test9</NodeA>
      <NodeB>test8</NodeB>
      <NodeC>
         <Att>test8</Att>
         <ValueN>6.0</ValueN>
      </NodeC>
</Node>

我希望合并的xml看起来像这样:
<?xml version="1.0" encoding="utf-8"?>
<Node>
      <NodeA>test1</NodeA>
      <NodeB>test2</NodeB>
      <NodeNEW>test4</Att>
      <Value1>1.0</Value1>
      <ValueN>5.0</ValueN>
</Node>
<Node>
      <NodeA>test1</NodeA>
      <NodeB>test7</NodeB>
      <NodeNEW>test8</NodeNEW>
      <Value1>2.0</Value1>
      <ValueN>6.0</ValueN>
</Node>
<Node>
      <NodeA>test9</NodeA>
      <NodeB>test8</NodeB>
      <NodeNEW>test8</NodeNew>
      <Value1></Value1>
      <ValueN>6.0</ValueN>

</Node>

因此,我创建了具有不同Value1,... ValueN的唯一键NodeA> NodeB> NodeNEW,如果此唯一键未出现在其各自的xml中,则它们将不分配任何内容。

什么是最有效的方法?

最佳答案

下面的代码应该为您提供所需的结果,如果它未发布,它将不会显示以前的节点的值,但是您也可以尝试并使其正常工作。这里的想法是使用XMLReader读取项目并在同一迭代中更新现有节点。

    static void Main(string[] args) {

  //Ideally you should have well formed xml with root element as eg given below
  //but since it is stream it is possible but not sure how much control you have on it.
  //eg: <Nodes><Node1/><Node2/>...</Nodes>

  //Reading your data from locally stored stream files
  var streamFiles=new[] { @"C:\temp\stack\xml1.xml", @"C:\temp\stack\xmlN.xml" };

  var dict = new Dictionary<int,XElement>();

  foreach(var streamFile in streamFiles) {
    using(var reader=XmlReader.Create(streamFile, new XmlReaderSettings { ConformanceLevel=ConformanceLevel.Fragment })) {
      var nodeNo=0;
      while(reader.MoveToContent()==XmlNodeType.Element) {
        var element=XNode.ReadFrom(reader) as XElement;
        //Now merge the data. Yahoo
        XElement currentElement;
        if(!dict.TryGetValue(nodeNo, out currentElement)) {
          currentElement = new XElement("Node");
          dict.Add(nodeNo, currentElement);
        }

        foreach(var el in element.Elements().Where(e => !e.HasElements)) {
          currentElement.SetElementValue(el.Name, el.Value);
        }

        currentElement.SetElementValue("NodeNEW",
          element.Elements().Where(e => e.HasElements)
            .SelectMany(e => e.Elements()
              .Where(w => w.Name=="Att"))
            .FirstOrDefault().Value);

        currentElement.Add(element.Elements().Where(e => e.HasElements)
          .SelectMany(e => e.Elements()
            .Where(w => w.Name!="Att")));

        nodeNo++;
      }
    }
  }

  using(var writer=XmlWriter.Create(@"C:\temp\stack\xmlMerged.xml",
    new XmlWriterSettings {
      ConformanceLevel=ConformanceLevel.Fragment,
      Indent=true
    })) {
    foreach(var element in dict.Values) {
      element.WriteTo(writer);
    }
  }
}

关于c# - 如何合并xml流,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31058500/

10-17 00:26