覆盖另一个Xml文件中的值

时间:2013-02-15 16:26:33

标签: c# linq-to-xml

寻找合并到XML文件的方法,其中第二个文件中的已修改属性应覆盖第一个文件中对象的值。看起来像这样应该可以使用linq到xml,但在如何做到这一点时遇到一些麻烦。

例如,请使用以下两个XML文件:

文件1:

<root>
   <foo name="1">
     <val1>hello</val1>
     <val2>world</val2>
   </foo>
   <foo name="2">
     <val1>bye</val1>
   </foo>
</root>

文件2:

<root>
   <foo name="1">
     <val2>friend</val2>
   </foo>
</root>

期望的最终结果是将文件2合并到文件1中并以

结束
<root>
   <foo name="1">
     <val1>hello</val1>
     <val2>friend</val2>
   </foo>
   <foo name="2">
     <val1>bye</val1>
   </foo>
</root>

子'foo'元素应由其'name'值唯一标识,文件2中的任何设置值都会覆盖文件1中的值。

非常感谢任何正确方向的指示,谢谢!

2 个答案:

答案 0 :(得分:0)

你可以只是迭代和更新值 - 不知道你想要的通用程度如何...

class Program
{
    const string file1 = @"<root><foo name=""1""><val1>hello</val1><val2>world</val2></foo><foo name=""2""><val1>bye</val1></foo></root>";

    const string file2 = @"<root><foo name=""1""><val2>friend</val2></foo></root>";

    static void Main(string[] args)
    {
        XDocument document1 = XDocument.Parse(file1);
        XDocument document2 = XDocument.Parse(file2);

        foreach (XElement foo in document2.Descendants("foo"))
        {
            foreach (XElement val in foo.Elements())
            {
                XElement elementToUpdate = (from fooElement in document1.Descendants("foo")
                                            from valElement in fooElement.Elements()
                                            where fooElement.Attribute("name").Value == foo.Attribute("name").Value &&
                                                 valElement.Name == val.Name
                                            select valElement).FirstOrDefault();

                if (elementToUpdate != null)
                    elementToUpdate.Value = val.Value;

            }
        }

        Console.WriteLine(document1.ToString());

        Console.ReadLine();

    }
}

答案 1 :(得分:0)

您可以从这两个构建新的xml:

XDocument xdoc1 = XDocument.Load("file1.xml");
XDocument xdoc2 = XDocument.Load("file2.xml");

XElement root =
    new XElement("root",
        from f in xdoc2.Descendants("foo").Concat(xdoc1.Descendants("foo"))
        group f by (int)f.Attribute("name") into foos
        select new XElement("foo",
            new XAttribute("name", foos.Key),
            foos.Elements().GroupBy(v => v.Name.LocalName)
                           .OrderBy(g => g.Key)
                           .Select(g => g.First())));

root.Save("file1.xml");

因此,首先选择第二个文件中的foo元素,它们将优先于第一个文件中的foo元素(当我们进行分组时)。