2016-09-19 4 views
0

Я загрузил HTML в HTML-документ. Теперь я хочу получить/выбрать каждый dt с каждым dd который принадлежит к dt и сохраните его в массиве для дальнейшего использования. Я уже пробовал синтаксис XPath, как упоминалось в http://www.w3schools.com/xsl/xpath_axes.asp, но он вообще не работал. Я только что получил NullReferenceException. Но что я делаю неправильно?Как получить доступ к текущему узлу и потомкам из документа HTML с пакетом agility?

Пожалуйста, обратите внимание, что иногда есть 2 или более **dd** элементов для одного **dt**. Я хочу добавить каждый элемент **dd** в соответствующий **dt**.

Большое спасибо заранее.

<dl> 
    <dt id="one">one</dt> 
    <dd>some text</dd> 
    <dt id="two">two</dt> 
    <dd>some text</dd> 
    <dt id="three">three</dt> 
    <dd>some text</dd> 
    <dd>some text</dd> 
    <dt id="four">four</dt> 
    <dd>some text</dd> 
    and so on... 
</dl> 

ответ

0

Там нет прямой связи между dt и dd элементов, поэтому лично я не нашел способ, чтобы обеспечить вам решение с помощью XPath. XSLT может быть вариантом, однако я не нашел быстрый и легкий способ использования XSLT. Поскольку вы используете C# Я сделал быстрый прототип-функции, как это может выглядеть в C#:

public static void Main(string[] args) 
     {    
      Dictionary<string, List<string>> dt = new Dictionary<string, List<string>>();   

      using(XmlReader reader = XmlReader.Create(@"data.xml")){ 
       bool incomingDd = false; 
       while(reader.Read()){ 
        switch(reader.NodeType){ 
         case XmlNodeType.Element:        
          if(String.Equals(reader.Name, "dt", StringComparison.OrdinalIgnoreCase)){ 
           dt.Add(reader.GetAttribute("id"), new List<string>()); 
          } 
          else if(String.Equals(reader.Name, "dd", StringComparison.OrdinalIgnoreCase)){ 
           incomingDd = true;         
          } 
          break; 

         case XmlNodeType.Text:         
          if(incomingDd && !String.IsNullOrEmpty(reader.Value)){         
           dt.Values.ElementAt(dt.Count -1).Add(reader.Value); 
           incomingDd = false; 
          } 
          break; 
        } 
       } 
      } 

      foreach(var item in dt){ 
       Console.WriteLine($"{item.Key} {item.Value.Count()}:"); 
       foreach(var dd in item.Value){ 
        System.Console.WriteLine($"\t{dd}"); 
       } 
      } 
     } 

Это может быть не самый красивый код, чтобы соответствовать вашим потребностям, но это должно дать вам представление о том, как решить твоя проблема.

+0

Hi codeguy, мои самые глубокие извинения за мой поздний ответ, но я был занят на прошлой неделе. Большое спасибо за ваш ответ. Это мне очень помогло! –

+0

Без проблем, рад помочь! Не могли бы вы отметить это как ответ, если это решение вашей проблемы? Спасибо. – codeguy