当前位置:编程学习 > C#/ASP.NET >>

求解答,多个xml文档合并的问题~~~~~~~~~~~~~~~~~~~~~~~

--------------------编程问答-------------------- 帮顶,, --------------------编程问答-------------------- 谢谢,求大神出现啊 --------------------编程问答--------------------
可以的。
不过看你要合并的xml里面的元素会不会完全相同啊。如果相同你要怎么处理。
xml里面的层数会不会一样。这都要考虑。
起码要知道怎么个合并法。 --------------------编程问答-------------------- 回楼上的,元素不一定会完全相同,不相同的就追加
层数会不一样
就跟我列子上的那样 --------------------编程问答-------------------- 两个XML结构不一样,只能靠代码一一判断再合并 --------------------编程问答-------------------- 1.xml有的元素 2.xml不一定有。2.xml有的元素1不一定有。
这就麻烦,一个一个元素的判断。还要确定元素所在的层数。
一一逐个判断。再合并。

你多个要合并的xml文件可以规范一点吗。
--------------------编程问答-------------------- 2.xml再来一个<F V="100"/>或者 <C VA="50"/>
那怎么办,怎么个合并法。没有规律是没法合并的。
<?xml version="1.0" encoding="utf-8"?>
<A>
  <B>
    <Item SystemTool="1" ToolType="2" Role="" JC="" AC="" DRC=""/>
    <Item1 a="1" b="2"/>
  </B>
  <C VA="5"/>
  <D VALUES="6"/>
  <F V="100"/>
  <E>
     <G V="11"/>
     <C VA="50"/>
  </E>
</A>
--------------------编程问答-------------------- 用 linq2xml:(.net 3.5 以上可用)


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

namespace Linq2Xml_MergeXml
{
    class Program
    {
        static void Main(string[] args)
        {
            var xml1 = @"<?xml version=""1.0"" encoding=""utf-8""?>
                            <A>
                              <B>
                                <Item SystemTool=""1"" ToolType=""2"" Role="""" JC="""" AC=""3"" DRC=""""/>
                              </B>
                              <C VALUES=""4""/>
                              <E>
                                 <F V=""10""/>
                              </E>
                            </A>";
            Console.WriteLine(xml1);
            Console.WriteLine("------------");

            var xml2 = @"<?xml version=""1.0"" encoding=""utf-8""?>
                            <A>
                              <B>
                                <Item SystemTool=""1"" ToolType=""2"" Role="""" JC="""" AC="""" DRC=""""/>
                                <Item1 a=""1"" b=""2""/>
                              </B>
                              <C VA=""5""/>
                              <D VALUES=""6""/>
                              <E>
                                 <G V=""11""/>
                              </E>
                            </A>";

            var xdoc1 = XDocument.Parse(xml1);
            var xdoc2 = XDocument.Parse(xml2);
            xdoc1.Merge(xdoc2);
            Console.WriteLine(xdoc1.ToString());
            Console.Read();
        }

    }

    public static class XDocumentExtension
    {
        public static void Merge(this XDocument xdoc, XDocument mergedXdoc)
        {
            foreach (var node in xdoc.Descendants())
            {
                // Add nonexistence attributes
                var target = mergedXdoc.Descendants(node.Name);
                foreach (var att in target.Attributes())
                {
                    // Check existence attributes by name not value
                    if (!node.Attributes().Select(t => t.Name.ToString())
                        .Contains(att.Name.ToString()))
                        node.Add(new XAttribute(att));
                }
                // Add nonexistence nodes
                var targetChilds = target.Descendants();
                var existsNodeNames = node.Descendants().Select(n => n.Name);
                var noExistNodes = targetChilds.Where(t => !existsNodeNames.Contains(t.Name));
                foreach (var newNode in noExistNodes)
                    node.LastNode.AddAfterSelf(newNode);
                
            }
        }

    }
}
--------------------编程问答-------------------- Merge 方法有点问题,修改下:

public static void Merge(this XDocument xdoc, XDocument mergedXdoc)
{
    foreach (var node in xdoc.Descendants())
    {
        // Add nonexistence attributes
        var target = mergedXdoc.Descendants(node.Name);
        foreach (var att in target.Attributes())
        {
            // Check existence attributes by name not value
            if (!node.Attributes().Select(t => t.Name.ToString())
                .Contains(att.Name.ToString()))
                node.Add(new XAttribute(att));
        }
        // Add nonexistence nodes
        var targetChilds = target.Descendants();
        var existsNodeNames = node.Descendants().Select(n => n.Name);
        var noExistNodes = targetChilds.Where(t => !existsNodeNames.Contains(t.Name) 
                                                   && t.Parent.Name == node.Name);
        foreach (var newNode in noExistNodes)
            node.Add(newNode);                
    }
}
--------------------编程问答-------------------- --------------------编程问答-------------------- --------------------编程问答-------------------- 谢谢楼上的所有回答,我试试(JustACoder)的方法 --------------------编程问答-------------------- 回7楼,是元素不一定一样多,有可能出现你说的2.xml多一个<F/> ,然后需要的就是在3.xml里也出现这个<F/> --------------------编程问答-------------------- 有高人知道不是用linq的方法吗  --------------------编程问答-------------------- 我给你一个吧,要求:第一层根目录名字相同(例如都为A),并且合并不会出现名字或者属性的冲突(例如不会2个文件都存在C节点且都有属性 Type)

public static XmlDocument Merge(XmlDocument xd1, XmlDocument xd2)
        {
            XmlNode xnRoot1 = xd1.SelectSingleNode("/").ChildNodes[1];
            XmlNode xnRoot2 = xd2.SelectSingleNode("/").ChildNodes[1];
            string rootName = xnRoot2.Name;
            for (int i = 0; i < xnRoot2.ChildNodes.Count; i++)
            {
                string nodeName = xnRoot2.ChildNodes[i].Name;
                if (xnRoot1.SelectNodes(nodeName).Count == 0)
                {
                    XmlNode xnTemp = xd1.ImportNode(xnRoot2.ChildNodes[i], true);
                    xnRoot1.AppendChild(xnTemp);               
                }
                else
                {
                    XmlNode xnDest = xnRoot1.SelectNodes(nodeName)[0];
                    for (int j = 0; j < xnRoot2.ChildNodes[i].ChildNodes.Count; j++)
                    {
                        XmlNode xnTemp = xd1.ImportNode(xnRoot2.ChildNodes[i].ChildNodes[j], true);                        
                        xnDest.AppendChild(xnTemp);                        
                    }
                    for (int k = 0; k < xnRoot2.ChildNodes[i].Attributes.Count; k++)
                    {
                        XmlAttribute xaTemp = xd1.CreateAttribute(xnRoot2.ChildNodes[i].Attributes[k].Name);
                        xaTemp.Value = xnRoot2.ChildNodes[i].Attributes[k].Value;
                        xnDest.Attributes.Append(xaTemp);                        
                    }
                }
            }

            return xd1;
        }

        static void Main(string[] args)
        {
            var xml1 = @"<?xml version=""1.0"" encoding=""utf-8""?>
                            <A>
                              <B>
                                <Item SystemTool=""1"" ToolType=""2"" Role="""" JC="""" AC=""3"" DRC=""""/>
                              </B>
                              <C VALUES=""4""/>
                              <E>
                                 <F V=""10""/>
                              </E>
                            </A>";           

            var xml2 = @"<?xml version=""1.0"" encoding=""utf-8""?>
                            <A>
                              <B>
                                <Item SystemTool=""1"" ToolType=""2"" Role="""" JC="""" AC="""" DRC=""""/>
                                <Item1 a=""1"" b=""2""/>
                              </B>
                              <C VA=""5""/>
                              <D VALUES=""6""/>
                              <E>
                                 <G V=""11""/>
                              </E>
                            </A>";

            XmlDocument xdoc1 = new XmlDocument();
            xdoc1.LoadXml(xml1);
            XmlDocument xdoc2 = new XmlDocument();
            xdoc2.LoadXml(xml2);

            XmlDocument result = Merge(xdoc1, xdoc2);            
        }
--------------------编程问答-------------------- xml有的元素 2.xml不一定有。2.xml有的元素1不一定有。
这就麻烦,一个一个元素的判断。还要确定元素所在的层数。
一一逐个判断。再合并。 --------------------编程问答-------------------- 谢谢15楼的,我试试 --------------------编程问答--------------------
引用 15 楼 catchdream 的回复:
我给你一个吧,要求:第一层根目录名字相同(例如都为A),并且合并不会出现名字或者属性的冲突(例如不会2个文件都存在C节点且都有属性 Type)
C# code

public static XmlDocument Merge(XmlDocument xd1, XmlDocument xd2)
        {
            XmlNode xnRoot1 = xd1.Select……


if (xnRoot1.SelectNodes(nodeName).Count == 0)  这句报错提示 “表达式的计算结果必须为节点集。”
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,