如何从xml节点查询值?

Ian*_*oyd 17 sql-server xpath sql-server-2005 sqlxml

我有一个包含XML列的表:

CREATE TABLE Batches( 
   BatchID int,
   RawXml xml 
)
Run Code Online (Sandbox Code Playgroud)

xml包含以下项目:

<GrobReportXmlFileXmlFile>
   <GrobReport>
       <ReportHeader>
          <OrganizationReportReferenceIdentifier>1</OrganizationReportReferenceIdentifier>
          <OrganizationNumber>4</OrganizationNumber>
       </ReportHeader>
  </GrobReport>
   <GrobReport>
       <ReportHeader>
          <OrganizationReportReferenceIdentifier>2</OrganizationReportReferenceIdentifier>
          <OrganizationNumber>4</OrganizationNumber>
       </ReportHeader>
  </GrobReport>
   <GrobReport>
       <ReportHeader>
          <OrganizationReportReferenceIdentifier>3</OrganizationReportReferenceIdentifier>
          <OrganizationNumber>4</OrganizationNumber>
       </ReportHeader>
  </GrobReport>
   <GrobReport>
       <ReportHeader>
          <OrganizationReportReferenceIdentifier>4</OrganizationReportReferenceIdentifier>
          <OrganizationNumber>4</OrganizationNumber>
       </ReportHeader>
  </GrobReport>
Run Code Online (Sandbox Code Playgroud)

我想要的是生成一个集合,其中包含:

OrganizationReportReferenceNumber  OrganizationNumber
=================================  ==================
1                                  4
2                                  4
3                                  4
4                                  4
Run Code Online (Sandbox Code Playgroud)

我试过了:

SELECT 
    foo.value('/ReportHeader/OrganizationReportReferenceIdentifier') AS ReportIdentifierNumber,
    foo.value('/ReportHeader/OrganizationNumber') AS OrginazationNumber
FROM CDRBatches.RawXML.query('/GrobReportXmlFileXmlFile/GrobReport/ReportHeader') foo
Run Code Online (Sandbox Code Playgroud)

但这不起作用.我试过了:

SELECT 
    foo.value('/ReportHeader/OrganizationReportReferenceIdentifier') AS ReportIdentifierNumber,
    foo.value('/ReportHeader/OrganizationNumber') AS OrginazationNumber
FROM RawXML.nodes('/GrobReportXmlFileXmlFile/GrobReport/ReportHeader') bar(foo)
Run Code Online (Sandbox Code Playgroud)

但这不起作用.所述的XPath表达式

/GrobReportXmlFileXmlFile/GrobReport/ReportHeader
Run Code Online (Sandbox Code Playgroud)

是正确的; 在任何其他xml系统中它返回:

<ReportHeader>
    <OrganizationReportReferenceIdentifier>1</OrganizationReportReferenceIdentifier>
    <OrganizationNumber>4</OrganizationNumber>
</ReportHeader>
<ReportHeader>
    <OrganizationReportReferenceIdentifier>2</OrganizationReportReferenceIdentifier>
    <OrganizationNumber>4</OrganizationNumber>
</ReportHeader>
<ReportHeader>
    <OrganizationReportReferenceIdentifier>3</OrganizationReportReferenceIdentifier>
    <OrganizationNumber>4</OrganizationNumber>
</ReportHeader>
<ReportHeader>
    <OrganizationReportReferenceIdentifier>4</OrganizationReportReferenceIdentifier>
    <OrganizationNumber>4</OrganizationNumber>
</ReportHeader>
Run Code Online (Sandbox Code Playgroud)

所以,这是从我的疑问,我会很明显喜欢看到的.在阅读了十几个Stackover问题和答案之后,我就没有更接近解决问题了.

Bog*_*ean 30

SELECT  b.BatchID,
        x.XmlCol.value('(ReportHeader/OrganizationReportReferenceIdentifier)[1]','VARCHAR(100)') AS OrganizationReportReferenceIdentifier,
        x.XmlCol.value('(ReportHeader/OrganizationNumber)[1]','VARCHAR(100)') AS OrganizationNumber
FROM    Batches b
CROSS APPLY b.RawXml.nodes('/CasinoDisbursementReportXmlFile/CasinoDisbursementReport') x(XmlCol);
Run Code Online (Sandbox Code Playgroud)

演示:SQLFiddle

  • 这有效; 我不知道如何,但它有效。`x(XmlCol)` 在做什么?我假设`x` 是一个任意标识符,我假设`XmlCol` 是一个任意标识符。此查询中发生了什么?而且,我假设`CROSS APPLY` 是`FULL OUTER JOIN ON 1=1` 的同义词,因此该表正在连接到自身。如果没有额外的连接,是否无法查询值? (2认同)
  • `nodes()` 调用的语法是 `XmlSourceColumn.nodes() AS Table(XmlResultsColumn)`。`x` 是 `nodes(...)` 方法调用的别名 ([link](http://msdn .microsoft.com/en-us/library/ms188282.aspx))。`XmlCol` 是 `nodes()` 方法生成的 xml 列的别名。`nodes()` 方法将提取所有 `/CasinoDisbursementReportXmlFile/CasinoDisbursementReport` 元素(别名“x”)。`CROSS APPLY` ([link](http://msdn.microsoft.com/en-us/library/ms175156(v=SQL.90).aspx)) 用于调用函数/方法/查询(`nodes ()` 在本例中)适用于“APPLY”左侧(“Batches”)的每一行。 (2认同)

Eri*_*ice 5

这有效,已经过测试...

SELECT  n.c.value('OrganizationReportReferenceIdentifier[1]','varchar(128)') AS 'OrganizationReportReferenceNumber',  
        n.c.value('(OrganizationNumber)[1]','varchar(128)') AS 'OrganizationNumber'
FROM    Batches t
Cross   Apply RawXML.nodes('/GrobXmlFile/Grob/ReportHeader') n(c)  
Run Code Online (Sandbox Code Playgroud)