2013-05-10 20 views
8

Widzę, że przeoczam coś prostego, ale mam trudności z rekurencyjnym wyodrębnianiem węzłów z XDocumenta.Znajdowanie rekurencyjnie węzłów w XDocument

Mam XML podobny do tego:

<?xml version="1.0" encoding="iso-8859-1"?> 
<content> 
    <operation></operation> 
    <entry> 
    <observation> 
     <templateId/> 
     <code></code> 
     <value></value> 
     <entryRelationship> 
     <observation> 
      <templateId/> 
      <code></code> 
      <value></value> 
     </observation> 
     </entryRelationship> 
     <entryRelationship> 
     <observation> 
      <templateId/> 
      <code></code> 
      <value></value> 
     </observation> 
     </entryRelationship> 
    </observation> 
    </entry> 
</content> 

Myślałem, że mogę dostać wszystkie trzy węzły obserwacji za pomocą

foreach (XElement element in Content.Descendants("observation")) 
    ExamineObservation(element); 

Chociaż wygląda to działa tylko wtedy jeśli obserwacja nie mają dzieci. Próbowałem również .Ancestors i .DententantNodes, ale nie dostałem tego, co chciałem.

Mogę z łatwością napisać metodę rekursywną, która przyniesie mi to, czego potrzebuję, ale wolałbym użyć istniejącej metody, jeśli taka istnieje, szczególnie, że będę pracował z XML całkiem sporo na kilku projektach. Czy brakuje mi czegoś oczywistego?

Zauważ, że jakikolwiek węzeł, który mówi o obserwacji, będę musiał pobrać kod i wartość, więc w poniższym przykładzie będę musiał przetworzyć trzy węzły obserwacyjne. Gniazdowanie i ilość węzłów obserwacyjnych są arbitralne.

Dziękujemy za pomoc.

DODATEK

Wydaje mi się, że nie może być dając wystarczająco dużo informacji na temat XML. Nie sądziłem, że znaczniki będą miały znaczenie, ale przypuszczam, że powinienem je uwzględnić na wszelki wypadek. Poniżej znajduje się kilka pierwszych wierszy rzeczywistego komunikatu, który próbuję przeanalizować. Zamieniłem trochę tekstu na "..." dla prywatności.

<?xml version="1.0" encoding="iso-8859-1"?> 
<content xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <operation>update</operation> 
    <entry xmlns="urn:hl7-org:v3"> 
    <observation classCode="OBS" moodCode="EVN"> 
     <templateId root="..." /> 
     <code code="..." codeSystem="..." codeSystemName="..." displayName="..."> 
     </code> 
     <value xsi:type="..." code="..." codeSystem="..." codeSystemName="..." displayName="..."> 
     </value> 
     <entryRelationship typeCode="..."> 
     <observation classCode="..." moodCode="..."> 
+1

Niestety nie mogę złapać to, co jest tu źle, jeśli piszesz 'Console.WriteLine (element.Element ("Kodeks"));' w foreach ty otrzymam trzy kody zgodnie z oczekiwaniami –

+0

Nie. Prześledzimy przez to i nic nie otrzymuję. Całkowicie pomija poprzedni ExamineObservation (element). Xml używa przestrzeni nazw; Czy to by miało znaczenie? – Tim

+1

Uzgodnione z xeondev, to powinno działać. Jak zainicjalizować węzeł 'Content' w pętli foreach? – Gjeltema

Odpowiedz

8

Właśnie prowadził ten kod w VS2012, i to hit Console.WriteLine() 3 razy, wyprowadzanie węzeł obserwacji i zawartość poprawnie:

 XElement content = XElement.Parse(yourXmlStringWithNamespaceHeader); 
     foreach (XElement obs in content.Descendants("observation")) 
      Console.WriteLine(obs.ToString()); 

Edit - biorąc pod uwagę nowe informacje przestrzeni nazw, a przy użyciu XDocument zamiast XElement:

 XNamespace nse = "urn:hl7-org:v3"; 
     XDocument content = XDocument.Parse(yourXmlStringWithNamespaceHeader); 
     foreach (XElement ele in content.Descendants(nse + "observation")) 
      Console.WriteLine(ele.ToString()); 
+0

Dziękuję. Przykro mi, że nie uwzględniłem tych informacji na samym początku. Uczę się xml, jak to robię, i to było moje pierwsze uruchomienie z przestrzeniami nazw. Bardzo doceniam pomoc! – Tim

+0

Bez zmartwień - czasami trudno jest ułożyć coś w zadawnione pytanie, nie wiedząc, czy to będzie za mało. – Gjeltema