通过传递 XML 的动态节点名称获取值

Get value by passing dynamic node name of XML

我想通过动态传递节点名称来获取节点的值。

我正在使用这个 xml:

DECLARE @xml AS XML = '<AuditMsg>
  <SourceDb>TestDatabase</SourceDb>
  <SourceTable>Person</SourceTable>
  <PKFieldName>ID</PKFieldName>
  <UserId>sa</UserId>
  <DMLType>I</DMLType>
  <OldData />
  <ChangedData>
    <t xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <ID>4</ID>
      <FirstName>name 4</FirstName>
      <LastName>surname 4</LastName>
      <DateOfBirth>444444</DateOfBirth>
    </t>
  </ChangedData>
</AuditMsg>'
INSERT INTO @changed
    SELECT
        changed.col.value('local-name(.)', 'VARCHAR(100)') AS Name,
        changed.col.value('.[1]', 'VARCHAR(14)') AS Value,
        ROW_NUMBER() OVER (PARTITION BY changed.col.value('local-name(.)', 'VARCHAR(100)') ORDER BY (SELECT 0)) AS RecordId,
        changed.col.value('(/t/ID)[1]', 'INT') AS ApplicationID
    FROM 
        @ChangedData CD
    CROSS APPLY 
        CD.ChangedData.nodes('/t/*') AS changed(col)

在第 6 行,我将节点名称作为 ID 静态传递。我想动态传递该节点名称我正在尝试这样做

DECLARE @Attribute varchar(100) = 'ID'

INSERT INTO @changed
    SELECT
        changed.col.value('local-name(.)', 'VARCHAR(100)') AS Name,
        changed.col.value('.[1]', 'VARCHAR(14)') AS Value,
        ROW_NUMBER() OVER (PARTITION BY changed.col.value('local-name(.)', 'VARCHAR(100)') ORDER BY (SELECT 0)) AS RecordId,
        changed.col.value('(/t/' + @Attribute +')[1]', 'INT') AS ApplicationID
    FROM 
        @ChangedData CD
    CROSS APPLY 
        CD.ChangedData.nodes('/t/*') AS changed(col)

通过动态传递节点名称我收到此错误(XML 数据类型方法 "value" 的参数 1 必须是字符串文字)

我怎样才能做到这一点?

你是不是在找什么东西?

DECLARE @xml AS XML = 
'<AuditMsg>
  <SourceDb>TestDatabase</SourceDb>
  <SourceTable>Person</SourceTable>
  <PKFieldName>ID</PKFieldName>
  <UserId>sa</UserId>
  <DMLType>I</DMLType>
  <OldData />
  <ChangedData>
    <t xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <ID>4</ID>
      <FirstName>name 4</FirstName>
      <LastName>surname 4</LastName>
      <DateOfBirth>444444</DateOfBirth>
    </t>
  </ChangedData>
</AuditMsg>'

--你的外部定义变量

DECLARE @Attribute varchar(100) = 'ID'

--查询

SELECT @xml.value('(/AuditMsg
                    /ChangedData
                    /t
                    /*[local-name()=sql:variable("@Attribute")]
                    /text())[1]','nvarchar(max)');

XPath 将深入 <t> 并找到元素,其中元素的名称等于您通过 sql:variable() 传入的参数。在这个元素中,我们选择 text() 节点。