T-SQL中包含父节点的XPath查询问题求助
处理XML中包含父节点关联的XPath查询(SQL Server环境)
刚好碰到过类似的场景,来给你捋捋怎么在SQL Server里处理这种带父节点关联的XML查询~首先我先把你没写完的XML补全(方便示例),然后一步步给你演示不同的查询方式。
首先是完整的测试XML:
DECLARE @xml AS XML SET @xml = '<fields> <field> <id>1</id> <items> <item> <name>name1_1</name> <value>value1_1</value> </item> <item> <name>name1_2</name> <value>value1_2</value> </item> </items> </field> <field> <id>2</id> <items> <item> <name>name2_1</name> <value>value2_1</value> </item> </items> </field> </fields>'
1. 获取所有Item及其所属Field的ID
如果你想把每个item的name、value和它所属父节点field的id关联起来,可以用两种XPath写法:
方式一:基于层级路径向上查找
利用../../来定位父节点的父节点(也就是field节点),然后提取id值:
SELECT -- 向上两级找到field节点,取id item_node.value('(../../id)[1]', 'INT') AS FieldId, item_node.value('(name)[1]', 'VARCHAR(50)') AS ItemName, item_node.value('(value)[1]', 'VARCHAR(50)') AS ItemValue FROM @xml.nodes('/fields/field/items/item') AS T(item_node)
方式二:用ancestor轴更鲁棒的查找
如果担心XML结构后续可能调整(比如中间多了层级),用ancestor::field[1]直接定位最近的field祖先节点会更可靠:
SELECT -- 找到最近的field祖先节点,取其id item_node.value('(ancestor::field[1]/id)[1]', 'INT') AS FieldId, item_node.value('name[1]', 'VARCHAR(50)') AS ItemName, item_node.value('value[1]', 'VARCHAR(50)') AS ItemValue FROM @xml.nodes('/fields/field/items/item') AS T(item_node)
两种方式运行后都会得到如下结果:
| FieldId | ItemName | ItemValue |
|---|---|---|
| 1 | name1_1 | value1_1 |
| 1 | name1_2 | value1_2 |
| 2 | name2_1 | value2_1 |
2. 筛选特定Field下的Item
如果只想查询某个指定id的field下的item,可以在XPath里直接加筛选条件:
-- 只查询id=1的field下的item SELECT item_node.value('(ancestor::field[1]/id)[1]', 'INT') AS FieldId, item_node.value('name[1]', 'VARCHAR(50)') AS ItemName, item_node.value('value[1]', 'VARCHAR(50)') AS ItemValue FROM @xml.nodes('/fields/field[id=1]/items/item') AS T(item_node)
注意点
- 在SQL Server的XQuery中,
value()方法要求必须返回单个节点,所以一定要加[1]来确保只取第一个匹配的节点,否则会报错。 ancestor::轴是按从近到远的顺序返回祖先节点,[1]就是取最近的那个父级field,避免匹配到更上层的同名节点(如果有的话)。
内容的提问来源于stack exchange,提问作者Sebastian Ortner
相关产品推荐
相关产品推荐

