2016-04-24 3 views
0

В настоящее время я читаю xml, который имеет множество дочерних узлов и должен привязывать элементы дочерних узлов к gridview. Поэтому я перебираю узлы и добавляю datarows. Но у меня проблема в логике. Я создаю datarow, когда я прохожу через один узел. В этом узле есть 2 элемента. поэтому он сначала петли на первом элементе, и я привязываю этот элемент к строке. В том же цикле я добавляю dt.Rows.Add (dtrow). Таким образом, он добавляет 1 строку с одним элементом. Он снова петли и добавляет второй элемент в совершенно новую строку. Это не верно. Я хочу добавить 2 элемента в одну строку. Как я могу это исправить?логика для добавления datarow в datatable

foreach (XmlNode vers in g) 
{ 
    foreach (XmlNode vr in vers) 
    { 
     foreach (XmlNode a in vr) 
     { 
      dtrow = dt.NewRow(); 
      if (a.Name == "Title") 
      { 
       dtrow["Title"] = a.InnerText.Trim();  
      } 
      if (a.Name == "Location") 
      {  
       dtrow["Location"] = a.InnerText.Trim(); 
      } 
      dt.Rows.Add(dtrow); // this causes issue.    
     }   
    }  
} 

ответ

0

Вместо того чтобы делать вложенный цикл, как это, вы можете цикл только через элементы, скажем <e>, что соответствует строке в вашем DataTable т.е. число <e> будет равно количеству строк, вставленной в таблицу , На каждой итерации собирайте всю информацию из дочерних элементов текущего <e>, возможно используя SelectSingleNode().

Например, если предположить vers содержат элементы, которые соответствуют строкам DataTable «s, вы можете сделать что-то вроде этого:

foreach (XmlNode vr in vers) 
{ 
    dtrow = dt.NewRow(); 
    dtrow["Title"] = vr.SelectSingleNode("Title").InnerText.Trim(); 
    dtrow["Location"] = vr.SelectSingleNode("Location").InnerText.Trim(); 
    dt.Rows.Add(dtrow); 
} 

* Не забудьте использовать префикс пространства имен и менеджер, если XML за этот вопрос так же, как в вашем previous question


в ответ на ваш комментарий о делать это без менеджера пространства имен; игнорирование пространств имен возможно, но также, как правило, неодобрительно, потому что пространства имен существуют по какой-то причине.

Вы можете использовать local-name() функции XPath, чтобы соответствовать элементу без учета его имен, например:

dtrow["Title"] = vr.SelectSingleNode("*[local-name()='Title']") 
        .InnerText 
        .Trim(); 

или с помощью LINQ, чтобы соответствовать по XmlNode «ы Name свойства, подобного тому, что вы сделали первоначально:

dtrow["Title"] = vr.ChildNodes 
        .Cast<XmlNode>() 
        .First(o => o.Name == "Title") 
        .InnerText 
        .Trim(); 
+0

Я получаю сообщение об ошибке в строке vr.SelectSingleNode ("Title"). InnerText.Trim() в качестве ссылки на объект не установлен в экземпляр объекта. – Happy

+0

Я использую другой подход. Не так же в предыдущем вопросе, как вы упомянули. Я не хотел использовать диспетчер имен. – Happy

+0

@Happy Я упомянул о том, является ли * XML * одним и тем же, а не * подходом *. Итак, XML по-прежнему остается тем же самым? (т. е. XML по-прежнему имеет пространство имён по умолчанию) – har07

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