如果给定的字符串列表中存在特定元素值或其属性值,则获取XmlNodeList

时间:2013-07-10 14:53:53

标签: c# .net xmldocument xmlnodelist

我想从一个巨大的XML文件中获取XmlNodeList

条件: 我有List个唯一ID值,比如IDList
案例I:从IDList收集名为element ID的所有节点。
案例II:收集attribute名为element ID的XmlDocument之一的所有节点都有来自IDList的值。

简而言之,仅提取与IDList中给出的值匹配的节点。

我使用了一些循环,比如将这个XML加载到try { using (XmlReader reader = XmlReader.Create(URL)) { XmlDocument doc = new XmlDocument(); doc.Load(reader); XmlNodeList nodeList = doc.GetElementsByTagName("idgroup"); foreach (XmlNode xn in nodeList) { string id = xn.Attributes["id"].Value; string value = string.Empty; if (IDList.Contains(id)) { value = xn.ChildNodes[1].ChildNodes[1].InnerText; // <value> if (!string.IsNullOrEmpty(value)) { listValueCollection.Add(value); } } } } } catch {} 来迭代所有节点和ID值,但我正在寻找的是一些复杂的方法,可以更快,更快地完成。 因为循环不是大型XML文件的解决方案。

我的尝试:

<XLIFF>
    <xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2">
         <file date="2013-07-17">
              <body>
                   <id idName="test_001" >
                       <desc-group name="test_001">
                               <desc type="text"/>
                       </desc-group>
                       <result-unit idName="test_001_text">
                               <source>abcd</source>
                               <result>xyz</result>
                       </result-unit>
                   </id>
             </body>
       </file>
 </xliff>

XML(XLIFF)结构:

{{1}}

收集idName匹配的上述所有节点。

1 个答案:

答案 0 :(得分:1)

修改

这是一个可以解析您给出的示例的测试。它试图直接到达result节点,以使其保持尽可能高效。

[Test]
public void TestXPathExpression()
{
    var idList = new List<string> { "test_001" };
    var resultsList = new List<string>();

    // Replace with appropriate method to open your URL.
    using (var reader = new XmlTextReader(File.OpenRead("fixtures\\XLIFF_sample_01.xlf")))
    {
        var doc = new XmlDocument();
        doc.Load(reader);
        var root = doc.DocumentElement;

        // This is necessary, since your example is namespaced.
        var nsmgr = new XmlNamespaceManager(doc.NameTable);
        nsmgr.AddNamespace("x", "urn:oasis:names:tc:xliff:document:1.2");

        // Go directly to the node from which you want the result to come from.
        foreach (var nodes in idList
            .Select(id => root.SelectNodes("//x:file/x:body/x:id[@idName='" + id + "']/x:result-unit/x:result", nsmgr))
            .Where(nodes => nodes != null && nodes.Count > 0))
                resultsList.AddRange(nodes.Cast<XmlNode>().Select(node => node.InnerText));

    }

    // Print the resulting list.
    resultsList.ForEach(Console.WriteLine);
}

您只能使用XPath查询提取所需的节点。关于你如何去做的简短例子:

using (XmlReader reader = XmlReader.Create(URL))
{
    XmlDocument doc = new XmlDocument();
    doc.Load(reader);
    foreach(var id in IDList) {
        var nodes = doc.SelectNodes("//xliff/file/body/id[@idName='" + id + "']");
        foreach(var node in nodes.Where(x => !string.IsNullOrEmpty(x.ChildNodes[1].ChildNodes[1].InnerText)))
            listValueCollection.Add(node.ChildNodes[1].ChildNodes[1].InnerText);
    }
}

xpath表达式当然是一个例子。如果您愿意,可以发布XML示例,以便我能为您提供更准确的信息。