T-SQL解析XML列问题:无法正确匹配属性ID与对应值
问题分析与解决办法
你遇到的问题根源在于XPath表达式的路径查询范围出错了——原来的//是绝对路径查询,它会从整个XML文档的根节点开始搜索,而不是从当前遍历到的ProductAttributeNode节点往下查找。所以不管你处理的是哪个<ProductAttribute>节点,//ProductAttributeValue[1]/Value/text()都会返回整个XML里第一个ProductAttributeValue下的Value(也就是21),这就导致ID=10的行也拿到了错误的值。
修正后的T-SQL查询语句
把XPath里的绝对路径改成相对路径,用.来限定从当前节点开始搜索,就能匹配到每个属性对应的正确值:
SELECT ProductId as ProductId, ProductAttributeNode.value('(@ID)', 'int') as ProductAttributeMappingId, -- 关键修改:用相对路径替代绝对路径 ProductAttributeNode.value('(./ProductAttributeValue/Value/text())[1]', 'int') as ProductAttributeValueId FROM ( SELECT Id, ProductId, CAST(AttributesXml as XML) as AttributesXml, Sku FROM ProductAttributeCombination ) AS PAC CROSS APPLY AttributesXml.nodes('//Attributes/ProductAttribute') as T1(ProductAttributeNode)
关键修改点解释
- 原表达式
(//ProductAttributeValue[1]/Value/text())[1]://会遍历整个XML文档,找到所有ProductAttributeValue节点后取第一个,导致所有行都返回同一个值。 - 修改后的
(./ProductAttributeValue/Value/text())[1]:./表示从当前的ProductAttributeNode(也就是每个<ProductAttribute>节点)开始,查找它直属的ProductAttributeValue/Value节点,这样每个属性ID都会匹配到自己对应的Value,最终得到正确的映射:9→21,10→25。
你还可以进一步简化XPath(默认就是相对当前节点查询),直接写成(ProductAttributeValue/Value/text())[1],效果完全一致。
内容的提问来源于stack exchange,提问作者Brakke
相关产品推荐
相关产品推荐

