MSSQL-从XML属性中提取值,而不考虑位置

时间:2018-11-14 10:27:53

标签: sql-server xml

因此,如果您指定路径,我知道如何从XML提取值。 这是我到目前为止的查询:

with cte as
(
    select cast(ds.SelectBuilderXML as xml) as xml from [DataSelect] ds
)


select 
cte.xml.value('(/SqlBuilderSelect/Columns/Expression/Term/Value/Logical/@UniqueIdent)[1]', 'varchar(100)') as LogicalCol
from cte

我想做的是提取UniqueIdent属性文本,而不管XML中的路径如何。使用下面的XML的UniqueIdent,您可以看到在多个位置找到了UniqueIdent属性:

<SqlBuilderSelect MasterDimension="6">
  <Columns ColumnAlias="test">
    <Visible>true</Visible>
    <BaseType>Constant</BaseType>
    <Expressions>
      <Term>
        <Value Type="Constant">
          <Constant Name="test" />
        </Value>
      </Term>
    </Expressions>
  </Columns>
  <Columns ColumnAlias="test">
    <Visible>true</Visible>
    <BaseType>Logical</BaseType>
    <Expressions>
      <Term>
        <Value Type="Logical">
          <Logical UniqueIdent="4aa2c9a7-b745-4929-8ceb-f68fddc80ce1" />
        </Value>
      </Term>
    </Expressions>
  </Columns>
  <Where JoinType="AND">
    <Children>
      <Where JoinType="AND" whereID="ddddbb62-88a3-46a6-b2db-7ee51dd3699c">
        <Condition Operator="Equal" UniqueID="00ec987e-5d60-4d0d-b91b-1fb090725cb7">
          <FirstTerm ColumnBaseType="Logical">
            <Visible>true</Visible>
            <BaseType>Logical</BaseType>
            <Expressions>
              <Term>
                <Value Type="Logical">
                  <Logical UniqueIdent="19ae3aca-b1d6-4eea-b78c-86e8d62ba960" />
                </Value>
              </Term>
            </Expressions>
          </FirstTerm>
        </Condition>
      </Where>
    </Children>
  </Where>
  <JoinOverrides>
    <JoinOverride FromPath="" ToPath="test" JoinType="Left" subselectjoin="false" />
  </JoinOverrides>
  <ParametersDefinitions>
    <Parameter Name="EndDate" />
  </ParametersDefinitions>
  <SystemShortCode>fd015bf9-aed2-41e4-8923-a256934ae344</SystemShortCode>
</SqlBuilderSelect>

因此,要返回的结果基于上述XML:

UniqueIdent
------------------------------------    
4aa2c9a7-b745-4929-8ceb-f68fddc80ce1
19ae3aca-b1d6-4eea-b78c-86e8d62ba960

1 个答案:

答案 0 :(得分:0)

首先,我们需要选择要作为输出基础的XML节点。在这里,我们希望每个表行的每个<Logical>元素一个输出行。

XPath表达式//Logical将从文档中选择所有这些元素,并且T-SQL函数.nodes()将XPath应用于XML列。对于您的示例XML,这将产生两个元素。

这意味着我们在每个输入行中获得多个输出行,因此我们需要将函数结果“联接”到表/ CTE,并通过cross apply完成联接函数的结果。

最后,如果要从每个元素中使用.value()属性,我们想选择UniqueIdent

with cte as
(
    select cast(ds.SelectBuilderXML as xml) as xml from [DataSelect] ds
)
select T.Logical.value('@UniqueIdent', 'varchar(36)') as UniqueIdent
from cte cross apply cte.xml.nodes('//Logical') as T(Logical)