XPath提取SQL XML值

27

这是我的问题:从以下XML中,我想知道在给定步骤ID和组件ID的情况下,名称为“Enabled”的变量的值是否等于“Yes”,该XML位于一个列中。

'<xml>
  <box stepId="1">
    <components>
      <component id="2">
        <variables>
          <variable id="3" nom="Server" valeur="DEV1" />
          <variable id="4" nom="Enabled" valeur="Yes" />
        </variables>
      </component>
      <component id="3">
        <variables>
          <variable id="3" nom="Server" valeur="DEV1" />
          <variable id="4" nom="Enabled" valeur="No" />
        </variables>
      </component>
    </components>
  </box>
  <box stepId="2">
    <components>
      <component id="2">
        <variables>
          <variable id="3" nom="Server" valeur="DEV2" />
          <variable id="4" nom="Enabled" valeur="Yes" />
        </variables>
      </component>
      <component id="3">
        <variables>
          <variable id="3" nom="Server" valeur="DEV2" />
          <variable id="4" nom="Enabled" valeur="No" />
        </variables>
      </component>
    </components>
  </box>
</xml>'
3个回答

37

更新

我的建议是将XML分解成关系,然后以面向集合的方式对结果关系进行搜索和连接,而不是以过程方式搜索XML中的特定节点。以下是一个简单的XML查询,用于分解所需节点和属性:

select x.value(N'../../../../@stepId', N'int') as StepID
  , x.value(N'../../@id', N'int') as ComponentID
  , x.value(N'@nom',N'nvarchar(100)') as Nom
  , x.value(N'@valeur', N'nvarchar(100)') as Valeur
from @x.nodes(N'/xml/box/components/component/variables/variable') t(x)

然而,如果您必须使用一个XPath来准确检索所需值:
select x.value(N'@valeur', N'nvarchar(100)') as Valeur
from @x.nodes(N'/xml/box[@stepId=sql:variable("@stepID")]/
    components/component[@id = sql:variable("@componentID")]/
       variables/variable[@nom="Enabled"]') t(x)

如果stepID和component ID是列而不是变量,则在XPath过滤器中应使用sql:column()代替sql:variable。请参阅“在XML数据中绑定关系数据”(Binding Relational Data Inside XML Data)。
最后,如果您只需要检查存在性,可以使用exist() XML方法(exist())。
select @x.exist(
  N'/xml/box[@stepId=sql:variable("@stepID")]/
    components/component[@id = sql:variable("@componentID")]/
      variables/variable[@nom="Enabled" and @valeur="Yes"]') 

4
@x 是什么? - Ian Boyd
3
жҲ‘зҢңжөӢд»–еңЁSQL ServerжҹҘиҜўзӘ—еҸЈдёӯзҡ„иҜӯеҸҘдёӯдҪҝз”ЁдәҶDECLARE @x XML = (xml from question); жқҘжөӢиҜ•XMLпјҢдҪҶжҳҜд»Һзӯ”жЎҲдёӯеҲ йҷӨдәҶиҝҷйғЁеҲҶеҶ…е®№еӣ дёәе®ғжҳҜеӨҡдҪҷзҡ„гҖӮжҖ»д№ӢпјҢжҲ‘жҖҖз–‘е®ғжҳҜдёҖдёӘеҢ…еҗ«й—®йўҳдёӯXMLзҡ„еҸҳйҮҸгҖӮ - sirdank

4

1
这两个链接都已失效。我建议查看以下语言参考文档: https://learn.microsoft.com/en-us/sql/xquery/xquery-language-reference-sql-server?view=sql-server-2017 - Lachlan Ennis
链接已失效。 - user482745
1
@user482745:第一个链接运行良好 - 更新了第二个链接,现在也可以正常工作。 - marc_s

2
我认为你想要的xpath查询应该是这样的:

我认为你想要的xpath查询应该是这样的:

/xml/box[@stepId="$stepId"]/components/component[@id="$componentId"]/variables/variable[@nom="Enabled" and @valeur="Yes"]

这应该能为指定的$stepId和$componentId获取名称为“Enabled”且值为“Yes”的变量。这是假设您的xml以像您展示的那样的标签开头,而不是

如果SQL Server 2005 XPath很简单(我从未使用过),那么上面的查询应该可以工作。否则,其他人可能需要帮助您解决问题。

谢谢,那很有帮助。如果找到匹配项,我该如何返回true或false?或者返回0或1。 - joerage
我不确定。你可以尝试像这样的东西:如果计数(<您的xpath查询>)>= 1 选择1 否则 选择0 - Mike Cialowicz
您可以使用EXIST方法。Field.EXIST('xpath') - Robin Bennett

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接