2013-07-10 1 views
1

Я хотел бы получить XmlNodeList из огромного файла XML.Получить XmlNodeList, если конкретный элемент или его значение атрибута присутствует в данном списке строк

Условия: У меня есть List уникальных значений ID, скажем список_идентификаторов
Случай I: Соберите все узлы, где element называется ID имеет значение от список_идентификаторов.
Корпус II: Соберите все узлы, где один из attribute с именем idName element Идентификатор имеет значение из 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

@ Ioannis Karadimas: Спасибо, я просто обновил структуру XLIFF здесь , – Indigo

+0

Пожалуйста, проверьте мое сообщение. Я привел пример, который может его проанализировать. –

ответ

1

EDIT

Это тест, который можно разобрать на примере вы даете. Он пытается напрямую подключиться к узлу 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

Смежные вопросы