我有多个具有这种格式的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/