Finding Nodes Recursively in an XDocument

2019-06-16 10:13发布

I figure I am overlooking something simple, but I am having difficulty extracting nodes from an XDocument recursively.

I have XML similar to this:

<?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>

I thought I could get all three observation nodes using

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

Although it looks like this only works when observation does not have children. I also tried .Ancestors and .DecentantNodes, but didn't get what I wanted.

I can easily write a recursive method that gets me what I need, but I would rather use an existing method if there is one, especially since I will be working with XML quite a bit on several projects. Am I missing something obvious?

Note that any node that says observation, I will need to get the code and value from, so in the example below I will need to process three observation nodes. The nesting and quantity of observation nodes are arbitrary.

Thank you for any assistance.

ADDENDUM

It occurs to me that I may not be giving enough information about the XML. I didn't think tags would make a difference, but I suppose I should include them just in case. Below is the first several lines of an actual message I am attempting to parse. I did replace some text with "..." for privacy.

<?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条回答
虎瘦雄心在
2楼-- · 2019-06-16 10:52

I just ran this code in VS2012, and it hit the Console.WriteLine() 3 times, outputting the observation node and contents correctly:

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

Edit - taking into account the new namespace information, and using XDocument instead of XElement:

        XNamespace nse = "urn:hl7-org:v3";
        XDocument content = XDocument.Parse(yourXmlStringWithNamespaceHeader);
        foreach (XElement ele in content.Descendants(nse + "observation"))
            Console.WriteLine(ele.ToString());
查看更多
登录 后发表回答