有没有一种方法可以从xmlvalue.value方法中选择所有元素,而不是指定[1]

时间:2019-05-27 13:56:31

标签: sql xml tsql xml-parsing

我想访问所有实例,而不要在XMLvalues.value方法中指定,例如1

我已经使用外部应用加入了节点,但是我需要指定实例编号

SELECT
        Id                                                            ,
        XmlValues2.value('(date1)[1]', 'DateTime')  AS date1 ,
        XmlValues.value('(name)[1]', 'varchar(1299)')    AS bank   ,
        XmlValues.value('(country)[1]', 'varchar(1299)') AS Country    ,
FROM
        Temp_board I OUTER APPLY I.board.nodes('/Report/basicInfo/report') AS xmlTableInner(XmlValues2) 
        OUTER APPLY XmlValues2.nodes('/Report/basicInfo/bank') AS xmlTable(XmlValues)
WHERE
        Id ='235908235'         

所以我想要所有节点元素的结果,而不仅仅是第一个瞬间

附加的xml屏幕截图。我要访问所有交易实例。XML example

1 个答案:

答案 0 :(得分:0)

对于下一个问题,请尝试set up a MCVE。这是一个自运行示例,用于重现您的问题。并且请勿提供代码或数据作为图片。这意味着,其他人必须在...中键入此内容。

有个问题,即XML的图片不包含根标记,也不包含最终存在的名称空间。此外,目标<Transaction>元素在图片中完全为空...此外,您在问题中提供的代码与您显示的XML没有关系...

我想您可以理解,所有事情都必须是纯粹的猜测,而我的魔幻水晶球目前正在清洗中;-)

这次我为您做mcve。很多人只是在猜测要展示这些原理。尝试一下并尝试将其用于您的实际问题:

声明一个 mockup-XML

DECLARE @xml XML=
N'<SomeRootNode>
      <accountList>
        <Transaction SomeAttribute="blah1">
          <SomeSubElement subAttr="sub1">element1</SomeSubElement>
        </Transaction>
        <Transaction SomeAttribute="blah2">
          <SomeSubElement subAttr="sub2">element2</SomeSubElement>
        </Transaction>
        <Transaction SomeAttribute="blah3">
          <SomeSubElement subAttr="sub3">element3</SomeSubElement>
        </Transaction>
      </accountList>
    </SomeRootNode>';

-查询

SELECT tr.value('@SomeAttribute','varchar(100)') TheAttributeInTransactionElement
      ,tr.value('(SomeSubElement/@subAttr)[1]','varchar(100)') TheAttributeInTheSubElement
      ,tr.value('(SomeSubElement/text())[1]','varchar(100)') TheSubElementsContent
FROM @xml.nodes('/SomeRootNode/accountList/Transaction') A(tr);

简而言之:
 -.nodes()将深入<SomeRootNode>,深入<accountList>,并返回在此级别找到的所有<Transaction>元素  -.nodes()的结果是一个名为A的派生表,该表具有一个XML类型的单独列tr,代表一行中的每个Transaction。  -.value()可以直接选择属性  -.value()可以使用任何类型的XPath / XQuery从结构内部获取值。

更新您的XML还有一个级别Account

尝试一下

DECLARE @xml XML=
N'<SomeRootNode>
      <accountList>
       <Account>
        <number>1</number> 
        <Transaction SomeAttribute="blah1">
          <SomeSubElement subAttr="sub1">element1</SomeSubElement>
        </Transaction>
        <Transaction SomeAttribute="blah2">
          <SomeSubElement subAttr="sub2">element2</SomeSubElement>
        </Transaction>
        <Transaction SomeAttribute="blah3">
          <SomeSubElement subAttr="sub3">element3</SomeSubElement>
        </Transaction>
       </Account>
       <Account>
        <number>2</number> 
        <Transaction SomeAttribute="blah2-1">
          <SomeSubElement subAttr="sub2-1">element2-1</SomeSubElement>
        </Transaction>
        <Transaction SomeAttribute="blah2-2">
          <SomeSubElement subAttr="sub2-2">element2-2</SomeSubElement>
        </Transaction>
        <Transaction SomeAttribute="blah2-3">
          <SomeSubElement subAttr="sub2-3">element2-3</SomeSubElement>
        </Transaction>
       </Account>
      </accountList>
    </SomeRootNode>';

SELECT acc.value('(number/text())[1]','int') AccountNumber
      ,tr.value('@SomeAttribute','varchar(100)') TheAttributeInTransactionElement
      ,tr.value('(SomeSubElement/@subAttr)[1]','varchar(100)') TheAttributeInTheSubElement
      ,tr.value('(SomeSubElement/text())[1]','varchar(100)') TheSubElementsContent
FROM @xml.nodes('/SomeRootNode/accountList/Account') A(acc)
OUTER APPLY A.acc.nodes('Transaction') B(tr);

现在,我们可以对.nodes()使用两个调用。第一个将返回<Account>内的所有<accountList>元素,第二个将返回嵌套的<Transaction>元素,因为它正在使用A.acc作为输入。