2012-12-13 13 views
5

Mam metodę, która wykonuje się na zdarzeniu form_load, które wydaje się działać poprawnie, pomijając jedną linię.Zagnieżdżona pętla foreach odczytywania .xml i pisania obiektu do listy

private int ReadInPeople() 
{ 
    XmlNodeList nodeList = m_xmlDoc.DocumentElement.ChildNodes; 
    foreach (XmlNode PersonNode in nodeList) 
    { 
     Employee ccontact = new Employee(); 
     foreach (XmlNode PersonTag in PersonNode.ChildNodes) 
     { 
      switch (PersonTag.Name) 
      { 
       case "Employee": 
        ccontact.EmployeeNumber = PersonTag.FirstChild.Value; 
        break; 
       case "FirstName": 
        ccontact.FirstName = PersonTag.FirstChild.Value; 
        break; 
       case "LastName": 
        ccontact.LastName = PersonTag.FirstChild.Value; 
        break; 
       default: 
        break; 
      } 
     } 
     this.AddContact(ccontact); 
    } 
    return nodeList.Count; 
} 

Metoda AddContact dodaje obiekt pracownika do listy statycznej; jednak linia:

this.AddContact(ccontact); 

nie została wykonana.

Próbkę pliku XML:

<?xml version="1.0" encoding="utf-8"?> 
<people> 
    <person> 
    <Employee>123456789</Employee> 
    <FirstName>John</FirstName> 
    <LastName>Smith</LastName> 
    </person> 
    <person> 
    <Employee>987654321</Employee> 
    <FirstName>Ellen</FirstName> 
    <LastName>Wayne</LastName> 
    </person> 
</people> 

Próbowałem ustawienie przerwania i debugowania, i na pewno wystarczy, linia została całkowicie pomijane, jakby to było w ogóle nie było.

Zgodnie z radą Alana, zmieniłem wartość PersonTag.FirstChild.Value, gdy próbowałem odwołać się do węzła ChildNode, który nie istniał.

Zaktualizowana metoda pracy:

private int ReadInPeople() 
{ 
    XmlNodeList nodeList = m_xmlDoc.DocumentElement.ChildNodes; 
    foreach (XmlNode PersonNode in nodeList) 
    { 
     Employee ccontact = new Employee(); 
     foreach (XmlNode PersonTag in PersonNode.ChildNodes) 
     { 
      switch (PersonTag.Name) 
      { 
       case "Employee": 
        ccontact.EmployeeNumber = PersonTag.InnerText; 
        break; 
       case "FirstName": 
        ccontact.FirstName = PersonTag.InnerText; 
        break; 
       case "LastName": 
        ccontact.LastName = PersonTag.InnerText; 
        break; 
       default: 
        break; 
      } 
     } 
     this.AddContact(ccontact); 
    } 
    return nodeList.Count; 
} 
+1

Czy 'metoda AddContact' oznaczone' System.Diagnostics.ConditionalAttribute'? – eulerfx

+0

@eulerfx - Nie jestem tego świadomy - czy istnieje sposób weryfikacji? – tloveless

+0

Przejdź do definicji tej metody i sprawdź, czy jest ona oznaczona tym atrybutem. – eulerfx

Odpowiedz

2

można łatwo przeanalizować swoją xml z LINQ do XML: rozwiązania

XDocument xdoc = XDocument.Load(path_to_xml); 
var employees = xdoc.Descendants("person") 
        .Select(p => new Employee() 
        { 
         FirstName = (string)p.Element("FirstName"), 
         LastName = (string)p.Element("LastName"), 
         EmployeeNumber = (long)p.Element("Employee") 
        }); 

foreach (var ccontact in employees) 
    this.AddContact(ccontact); 

XmlDocument:

XmlNodeList nodeList = m_xmlDoc.DocumentElement.SelectNodes("person"); 
foreach (XmlNode PersonNode in nodeList) 
{ 
    Employee ccontact = new Employee(); 
    ccontact.LastName = PersonNode["LastName"].InnerText; 
    ccontact.FirstName = PersonNode["FirstName"].InnerText; 
    ccontact.EmployeeNumber = PersonNode["Employee"].InnerText; 
    this.AddContact(ccontact); 
} 
+0

+1. To znacznie ładniejsze rozwiązanie. Byłoby to trochę prostsze, gdybyś był w pętli bezpośrednio na potomkach zamiast najpierw tworzyć zapytanie. –

+0

@ OlivierJacot-Descombes dzięki! Pracowałem z Xml parsowania za pomocą XmlDocument wiele lat temu, ale teraz po prostu nie widzę powodu, aby używać go po Linq do Xml :) Powodem, dla którego zrobiłem pierwsze zapytanie jest separacja parsowania i zastosowanie logiki biznesowej (dodawanie do kontaktów) .. Ale kod mógł być jeszcze bardziej zwarty :) –

+0

Tak, 'System.Xml.Linq' ma znacznie prostszy i bardziej zaawansowany model obiektu do pracy. –

2

Czy jesteś pewien, że nie tylko uderzanie wyjątek? Zawiń logikę w try/catch i zobacz, czy trafi.

linie jak może to spowodować zerowe wyjątki odniesienia i może być powodem nie jesteś uderzając tej linii kodu:

PersonTag.FirstChild.Value 

Mogę sobie wyobrazić, nazywając ją na firstChild na pracownika, imię, Nazwisko lub wróci null, ponieważ nie zawierają węzła potomnego.

Może spróbuj:

PersonTag.InnerText 
+0

Zmieniłem każdą wartość PersonTag.FirstChild.Value na Persontag.Value, a teraz debugger trafił linię problemu - ale analizowane wartości są teraz zerowe. – tloveless

+1

Jednak popchnąłeś mnie właściwą drogą! Zaktualizowałem je do PersonTag.InnerText, aby wyszukać tekst zamiast Dziecka i wszystko jest w porządku. Dzięki! – tloveless

0

Build -> Rebuild Solution?

Czasami wiadomo, że pomaga.

Albo: Debug -> Exceptions... -> Thrown