1

我有一个加载到 XDocument 中的 xml 文件,我需要从中提取一个值,但我不确定最好的方法。我想出的大多数东西似乎都是矫枉过正或没有很好地利用 xml 规则。我有以下 xml 片段:

    <entry>
      <observation classCode="OBS" moodCode="EVN">
        <templateId root="2.16.840.1.113883.10.20.6.2.12" />
        <code code="121070" codeSystem="1.2.840.10008.2.16.4" codeSystemName="DCM" displayName="Findings">
        </code>
        <value xsi:type="ED">
          <reference value="#121071">
          </reference>
        </value>
      </observation>
    </entry>

可以有任意数量的<entry>节点,它们都将遵循类似的模式。root元素属性下的值templateId包含一个已知的 UID,该 UID 将该条目标识为我想要的条目。我需要得到参考值。

我的想法是找到正确的templateID节点,回到观察节点,找到<valuexsi:type="ED">然后得到参考值。这似乎过于复杂,我想知道是否有另一种方法可以做到这一点?

编辑

我收到的 xml 有时可以将 xml 嵌套在相同的节点名下。换句话说,<observation>可能位于另一个名为 的节点下<observation>

4

3 回答 3

1

您有问题,因为您的文档使用命名空间,而您的查询缺少它们。

首先,您必须xsi在 XML 中的某处(可能在最顶层元素中)找到命名空间声明。

它看起来像这样:

xmlns:xsi="http://test.namespace"

取命名空间 Uri 并XNamespace根据它的值创建实例:

var xsi = XNamespace.Get("http://test.namespace");

xsi并在您的查询中使用该变量:

var query = from o in xdoc.Root.Element("entries").Elements("entry").Elements("observation")
            let tId = o.Element("templateId")
            where tId != null && (string)tId.Attribute("root") == "2.16.840.1.113883.10.20.6.2.12"
            let v = o.Element("value")
            where v != null && (string)v.Attribute(xsi + "type") != null
            let r = v.Element("reference")
            where r != null
            select (string)r.Attribute("value");

var result = query.FirstOrDefault();

我已经针对以下 XML 结构对其进行了测试:

<root xmlns:xsi="http://test.namespace">
  <entries>
    <entry>
      <observation classCode="OBS" moodCode="EVN">
        <templateId root="2.16.840.1.113883.10.20.6.2.12" />
        <code code="121070" codeSystem="1.2.840.10008.2.16.4" codeSystemName="DCM" displayName="Findings">
        </code>
        <value xsi:type="ED">
          <reference value="#121071">
          </reference>
        </value>
      </observation>
    </entry>
  </entries>
</root>

查询#121071为它返回。

对于您的输入 XML,您可能必须更改第一行查询:

from o in xdoc.Root.Element("entries").Elements("entry").Elements("observation")

匹配<observation>XML 结构中的元素。

于 2013-04-19T08:37:51.963 回答
0

您可能必须在 LINQ 中包含命名空间。要检索它,您将执行以下操作:

XNamespace ns = xdoc.Root.GetDefaultNamespace();

然后在你的 linq 中:

var obsvlookfor = xdoc.Root.Descendants(ns + "observation")

我知道如果没有这个,我在检索数据时遇到了一些问题。并不是说它只是要记住的问题,特别是如果您的 XML 文件非常深入。

于 2013-04-19T01:59:33.977 回答
0

以下内容会有所帮助吗?

   XDocument xdoc = GetYourDocumentHere();
   var obsvlookfor =
       xdoc.Root.Descendants("observation")
           .SingleOrDefault(el => 
                el.Element("templateId")
                    .Attribute("root").Value == "root value to look for");

   if (obsvlookfor != null)
   {
       var reference = obsvlookfor
           .Element("value")
           .Element("reference").Attribute("value").Value;
   }

我的想法如下:

  1. 拉出文档中的所有观察元素
  2. 找到观察templateId元素具有root您正在寻找的属性的唯一一个(或空)
  3. 如果您找到该观察元素,请针对该元素下的元素拉出value属性。referencevalue
于 2013-04-19T00:13:32.600 回答