Search code examples
sqlsql-serverxmlxquery

SQL server XML query with xquery


I'm trying to reach "row" data below using xquery on sql server.

DECLARE @xmlData XML
SET @xmlData = '
<Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
  <Header>
    <WorkContext xmlns="http://oracle.com/weblogic/soap/workarea/">rO0ABXdbABh3ZWJsb2duNDAAAA==</WorkContext>
  </Header>
  <Body>
    <getReport xmlns:ns0="http://report_xml.org">
      <return>
        <pagekey>F1D96FB7ACFBA3BD5D5E77C5</pagekey>
        <rapor>
          <dataSet xmlns="http://report_xml.org/dataSet/201006">
            <dataTable>
              <id>ABC1</id>
              <row>
                <dim1>Paris</dim1>
                <dim2>Societe</dim2>
                <dim3>Car</dim3>
              </row>
              <row>
                <dim1>Paris</dim1>
                <dim2>Credit</dim2>
                <dim3>Car</dim3>
              </row>
            </dataTable>
          </dataSet>
        </rapor>
      </return>
    </getReport>
  </Body>
</Envelope>
'

When I use below code I can get the the "pagekey" value

; WITH XMLNAMESPACES ('http://report_xml.org/dataSet/201006' AS DS)
select @xmlData.query('/Envelope/Body/getReport/return/pagekey')

or I can reach the "dataSet" xml using this one

; WITH XMLNAMESPACES ('http://report_xml.org/dataSet/201006' AS DS)
select @xmlData.query('/Envelope/Body/getReport/return/rapor/DS:dataSet')

However, when I try to reach further down like

; WITH XMLNAMESPACES ('http://report_xml.org/dataSet/201006' AS DS)
select @xmlData.query('/Envelope/Body/getReport/return/rapor/DS:dataSet/dataTable/id')
or
select @xmlData.query('/Envelope/Body/getReport/return/rapor/DS:dataSet/dataTable/row')

Queries return empty.

what am I missing?


Solution

  • dataSet element introduces default namespace http://report_xml.org/dataSet/201006. Note that unlike prefixed namespace, descendant elements inherit default namespace from ancestor implicitly, so you should use the same prefix to access elements within dataSet:

    ; WITH XMLNAMESPACES ('http://report_xml.org/dataSet/201006' AS DS)
    select @xmlData.query('/Envelope/Body/getReport/return/rapor/DS:dataSet/DS:dataTable/DS:id')
    or
    select @xmlData.query('/Envelope/Body/getReport/return/rapor/DS:dataSet/DS:dataTable/DS:row')