1

XmlNodeList巨大な XML ファイルから取得したいと思います。

条件:List IDList などの一意の ID 値 を持っています
ケース I:element呼び出された ID が IDList からの値を持つすべてのノードを収集します。
ケース II:attribute ID の呼び出された idName の1 つがelementIDList からの値を持つすべてのノードを収集します。

つまり、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 に答える