C# 在XML中查找值
我将一个xml文件加载到一个XDocument中,需要从中提取一个值,但我不确定最好的方法。我想到的大多数东西似乎都有些过火,或者没有很好地利用xml规则。我有以下xml片段:C# 在XML中查找值,c#,xml,linq-to-xml,C#,Xml,Linq To Xml,我将一个xml文件加载到一个XDocument中,需要从中提取一个值,但我不确定最好的方法。我想到的大多数东西似乎都有些过火,或者没有很好地利用xml规则。我有以下xml片段: <entry> <observation classCode="OBS" moodCode="EVN"> <templateId root="2.16.840.1.113883.10.20.6.2.12" /> <code co
<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>
可以有任意数量的
节点,它们都将遵循类似的模式。templateId
元素的root
属性下的值包含一个已知的UID,该UID将此条目标识为我想要的条目。我需要得到参考值
我的想法是找到正确的templateID节点,返回到观察节点,找到
,然后获得参考值。这似乎过于复杂,我想知道是否有其他方法可以做到这一点
编辑
我接收的xml有时可以将xml嵌套在相同的节点名下。换句话说,
可能位于另一个名为
的节点下,是否需要以下帮助
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;
}
我的想法如下:
templateId
元素具有您要查找的root
属性的唯一一个(或null)value
元素下的reference
元素拉出value
属性按照下面的思路做一些事情会有帮助吗
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;
}
我的想法如下:
templateId
元素具有您要查找的root
属性的唯一一个(或null)value
元素下的reference
元素拉出value
属性您可能必须在LINQ中包含名称空间。要检索,请执行以下操作:
XNamespace ns = xdoc.Root.GetDefaultNamespace();
然后在你的linq中:
var obsvlookfor = xdoc.Root.Descendants(ns + "observation")
我知道我曾经在没有这个的情况下检索数据时遇到了一些问题。不要说这是一个需要记住的问题,特别是当您的XML文件非常深入时。您可能必须在LINQ中包含名称空间。要检索,请执行以下操作:
XNamespace ns = xdoc.Root.GetDefaultNamespace();
然后在你的linq中:
var obsvlookfor = xdoc.Root.Descendants(ns + "observation")
我知道我曾经在没有这个的情况下检索数据时遇到了一些问题。不要说这是一个需要记住的问题,特别是当您的XML文件非常深入时。您有问题,因为您的文档使用名称空间,而您的查询缺少名称空间 首先,您必须在XML中的某个地方找到
xsi
名称空间声明(可能在最顶层的元素中)
看起来是这样的:
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>
要匹配XML结构中的
元素,您会遇到问题,因为您的文档使用名称空间,而您的查询缺少名称空间
首先,您必须在XML中的某个地方找到xsi
名称空间声明(可能在最顶层的元素中)
看起来是这样的:
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>
匹配XML结构中的
元素。感谢您的回复。它看起来很棒,我认为,在正常情况下,这本可以做到。然而,我得到了一个空回。我相信这是因为观察节点嵌套在另一个观察节点下,所以它找到了根观察,而不是嵌套的。我本应该在我的问题中提出这一点,但我没有注意到。我仔细研究了您建议的代码,发现即使我更改了值以匹配外部观察节点,obsvlookfor仍然为null。@Tim观察值是如何嵌套在XML中的?因为这将影响您需要如何建立查询。我建议您将查询分解为若干部分,并在调试器的每个阶段检查返回的结果,以帮助您确定所需的最佳查询。嵌套观察可能会使查询更难管理,但并非不可能。感谢您的回复。它看起来很棒,我认为,在正常情况下,这本可以做到。然而,我得到了一个空回。我相信这是因为观察节点嵌套在另一个观察节点下,所以它找到了根观察,而不是嵌套的。我本应该在我的问题中提出这一点,但我没有注意到。我仔细研究了您建议的代码,发现即使我更改了值以匹配外部观察节点,obsvlookfor仍然为null。@Tim观察值是如何嵌套在XML中的?因为这将影响您需要如何建立查询。我建议将查询分解为若干部分,并在调试器的每个阶段检查返回的结果,以帮助您确定所需的最佳查询。嵌套观察可能会使查询更难管理,但并非不可能。您必须显示整个XML输入,因为在示例部分中使用了命名空间xsi
,但我们不知道它是如何声明的。您必须显示整个XML输入,因为在示例部分中使用了命名空间xsi
,但我们不知道它是如何声明的。