查询XML并更新某些元素

时间:2014-01-17 09:22:32

标签: c# xml linq xml-parsing linq-to-xml

我有一个格式如下的XML文件

<?xml version="1.0" ?>
<AA someattrib="xyz">
    <BB someOtherAttrib="xyz">
    <Title></Title>
        <CC>

            <myNode rowid="">
                <subNode1></subNode1>
                <subNode2></subNode2>
                <nodeOfInterest></nodeOfInterest>
            </myNode >
            <myNode rowid="">
                <subNode1> </subNode1>

            </myNode>
        </CC>
    </BB>
</AA>

我想使用Linq通过名称'MyNode'选择一个节点,其中rowid是我将从对象中的集合中获取的特定数字。一旦我得到myNode,我想更新子nodeOfInterest的值(如果它存在)。如果不存在,那么我想添加它。完成后我想保存文件。

这就是我现在所拥有的,但它可能不是正确的方法。

    foreach (User employee in Users)
    {

        XPathNavigator node = xNav.SelectSingleNode("/AA/BB/CC/myNode[@rowid = '"+employee.ID.ToString()+"']");
        XPathNodeIterator nodeIterator= node.SelectChildren("nodeOfInterest", "");
        if (nodeIterator.Count == 1)
        {

        }
        else
        {
        }

    }

有没有办法可以使用List和内存中的xmldoc之间的直接连接来完成?这将是一个大型列表和一个同样大的xml文件。我不认为运行循环并调用selectSingleNode是最有效的方法。

感谢您的投入

2 个答案:

答案 0 :(得分:2)

一个起点是创建一个Dictionary<string, XElement>将行ID映射到元素:

var dictionary = doc.Element("AA").Element("BB").Element("CC").Elements("myNode")
                    .ToDictionary(x => x.Attribute("rowId").Value);

然后:

foreach (User employee in Users)
{
    XElement myNode;
    if (dictionary.TryGetValue(employee.ID, out myNode))
    {
        // Use myNode
    }
    else
    {
        // Employee not found
    }
}

我个人更喜欢使用LINQ to XML(ElementsElementDescendants等)提供的选择方法,而不是SelectSingleNodeSelectChildren等。

答案 1 :(得分:0)

完整答案,在Jon的回复帮助下......

var doc = XDocument.Load("thefile.xml");
var dictionary = doc.Element("AA").Element("BB").Element("CC").Elements("myNode")
                .ToDictionary(x => x.Attribute("rowId").Value);

foreach (User employee in Users)
{
    XElement myNode;
    if (dictionary.TryGetValue(employee.ID, out myNode))
    {
            XElement nodeOfInterest = myNode.Elements("nodeOfInterest").FirstOrDefault();
            if (nodeOfInterest != null)
            {
                nodeOfInterest.Value = "update with this value";
            }
            else
            {
                XElement nodeOfInterest = new XElement("nodeOfInterest", "Add nodeOfInterest with this value");
                myNode.Add(newElement);
            }
    }

}
doc.Save("TheFile.xml");