1

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

条件: 我有一个List唯一的 ID 值,比如 IDList
案例一:从 IDList中收集所有被element称为 ID 的节点。
案例二:从IDList中收集ID的attribute被调用的idName之一具有值的所有节点。element

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

我使用一些循环来完成此操作,例如加载此 XML 以XmlDocument迭代所有节点和 ID 值,但我正在寻找一些复杂的方法来更快、更快速地完成它。因为循环不是大型 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
{}

XML (XLIFF) 结构:

<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>

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

4

1 回答 1

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 示例,以便我可以为您提供更准确的信息。

于 2013-07-10T15:08:42.053 回答