有很多关于根据子属性的值选择父节点的问题,但是它们似乎都没有解决这个问题。
我有一些XML:
<TABDISP>
<HEADER ORDER="1" PROMPT="Next of kin" />
<HEADER ORDER="2" PROMPT="Emergency contact" />
<ROW ORDER="1" PROMPT="Family name">
<FIELD ORDER="1" TYPE="TEXT" NAME="NKSurname" MANDATORY="N" />
<FIELD ORDER="2" TYPE="TEXT" NAME="ECSurname" MANDATORY="N" />
</ROW>
<ROW ORDER="2" PROMPT="Forenames">
<FIELD ORDER="1" TYPE="TEXT" NAME="NKForename" MANDATORY="N" />
<FIELD ORDER="2" TYPE="TEXT" NAME="ECForename" MANDATORY="N" />
</ROW>
</TABDISP>
从任何FIELD节点的上下文中,我想选择@ORDER属性匹配的HEADER节点(最终,我正在提取与该字段一起的提示)。
我已经尝试了../../HEADER[@ORDER=./@ORDER]
(我没想到会工作,但需要尝试),../../HEADER[@ORDER=self::node()/@ORDER]
,我现在想知道是否有合适的轴我可以使用远未找到一个合适的函数来返回我可以放在过滤器中的原始FIELD上下文节点。
我错过了什么?
答案 0 :(得分:0)
最近有理由再次对此进行讨论,答案分为两部分:
XPath 1.0无法实现。此问题在此网站上的另一个问题中得到了完全解答:XPath equivalent to current()
上面的答案不适用于SQL Server XML,但是通过进一步的实验,可以在SQL Server中执行类似以下操作:
declare @t xml = '<TABDISP>
<HEADER ORDER="1" PROMPT="Next of kin" />
<HEADER ORDER="2" PROMPT="Emergency contact" />
<ROW ORDER="1" PROMPT="Family name">
<FIELD ORDER="1" TYPE="TEXT" NAME="NKSurname" MANDATORY="N" />
<FIELD ORDER="2" TYPE="TEXT" NAME="ECSurname" MANDATORY="N" />
</ROW>
<ROW ORDER="2" PROMPT="Forenames">
<FIELD ORDER="1" TYPE="TEXT" NAME="NKForename" MANDATORY="N" />
<FIELD ORDER="2" TYPE="TEXT" NAME="ECForename" MANDATORY="N" />
</ROW>
</TABDISP>';
select field.xmlnode.value('(./@NAME)[1]', 'nvarchar(20)'),
field.xmlnode.value('(./@ORDER)[1]', 'int'),
header.xmlnode.value('(./@PROMPT)[1]', 'nvarchar(50)'),
header.xmlnode.value('(./@ORDER)[1]', 'int')
from @t.nodes('//FIELD') field(xmlnode)
cross apply @t.nodes('//HEADER') header(xmlnode)
where field.xmlnode.value('(./@ORDER)[1]', 'int') = header.xmlnode.value('(./@ORDER)[1]', 'int')