2013-07-10 32 views
1

我想從一個巨大的XML文件中獲取XmlNodeList如果給定的字符串列表中存在特定元素值或其屬性值,則獲取XmlNodeList

條件: 我有一個List唯一的ID值,說IDList表
案例一:收集所有地方element稱爲ID具有價值IDList表的節點。
案例二:收集ID爲element ID的attribute其中一個ID爲IDList的所有節點。

簡而言之,只提取與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匹配的所有節點。

+0

您附加的XML格式不正確,並且沒有描述文件的格式。另外,我不知道你的意思是XLIFF,但你的例子絕對不是這樣的:http://en.wikipedia.org/wiki/XLIFF –

+0

@Ianannis Karadimas:謝謝,我剛剛更新了XLIFF結構。 – Indigo

+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例子,這樣我可以給你更準確的東西。

+0

謝謝,我會試試這個解決方案。剛剛添加了一個XML節點的結構來提問。 XPath對此非常有用。不幸的是,之前從未使用過它。想嘗試並獲取更多信息。 – Indigo

+0

謝謝,它像一個魅力。我厭倦了所有XPath選項,但無法獲得正確的名稱空間。 在第二個示例中,與第一個示例中相同的XPath運行得很好。 – Indigo

相關問題