Question

I would like to read the xsi:type attribute from the "current" node in a SELECT statement. My XML looks like this:

 <ns2:data xmlns:ns2="http://mynamespace">
  <OrderLineItems>
    <OrderLineItem xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:DeactivationLineItem" id="1">
      <Product>
        <Id>5300</Id>
        <Description>DUMMY</Description>
        <Domain>ddd</Domain>
      </Product>
      <Quantity>1</Quantity>
    </OrderLineItem>
    <OrderLineItem xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:ActivationLineItem" id="4">
      <Product>
        <Id>5340</Id>
        <Description>DUMMY</Description>
        <Domain>aaa</Domain>
      </Product>
      <Quantity>1</Quantity>
    </OrderLineItem>
    <OrderLineItem xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:DeactivationLineItem" id="12">
      <Product>
        <Id>53200</Id>
        <Description>DUMMY</Description>
        <Domain>ccc</Domain>
      </Product>
      <Quantity>21</Quantity>
    </OrderLineItem>
  </OrderLineItems>
</ns2:data>

My select statement looks as follows:

;WITH XMLNAMESPACES('http://mynamespace' AS ns)
SELECT
,OrderLineItemID                = ref.value('@id', 'int')
,OrderLineItemParentID          = ref.value('@parentId', 'int')
,ProductID                      = NULLIF(ref.query('Product/Id').value('.', 'varchar(255)'),'')
,ProductDescription             = NULLIF(ref.query('Product/Description').value('.', 'varchar(255)'),'')
,ProductDomain                  = NULLIF(ref.query('Product/Domain').value('.', 'varchar(255)'),'')
,ProductAdditionalInfo          = NULLIF(ref.query('Product/AdditionalInfo').value('.', 'varchar(255)'),'')
,Quantity                       = ref.query('Quantity').value('.', 'int')

,LineItemType                   = ref.value('@xsi:type','varchar(max)')                 

FROM tTEMP_XMLTABLE
CROSS APPLY xmlFile.nodes('/ns:data/OrderLineItems/OrderLineItem') R(ref) 

My problem is the line LineItemType as it throws an error: The XQuery syntax '@{http://www.w3.org/2001/XMLSchema-instance}:type' is not supported

It is strange, because I am able to read a single type if I don't use the CROSS APPLY:

WITH  XMLNAMESPACES ('http://mynamespace' as p)
SELECT CAST(xmlFile as XML).value('(/p:data/OrderLineItems/OrderLineItem/@xsi:type)[1]','nvarchar(max)')
from tTEMP_XMLTABLE;

The second statement works on SQL Server 2005. Is there a possibility to read the xsi:type attribute when using cross apply?

Thanks for the help

Was it helpful?

Solution

This worked for me in SQL Server 2008 SP1 (you didn't specify version, so I'm not sure if that is what you have or not). Not sure if it's possible for you to get your xml or a copy of your xml into an untyped xml field like I have here, but that might help you get around the schema-bound issue from the link I gave you above.

DECLARE @tmp_xml TABLE (id int identity, data xml)

INSERT INTO @tmp_xml (data)
VALUES ('<ns2:data xmlns:ns2="http://mynamespace">
  <OrderLineItems>
    <OrderLineItem xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:DeactivationLineItem" id="1">
      <Product>
        <Id>5300</Id>
        <Description>DUMMY</Description>
        <Domain>ddd</Domain>
      </Product>
      <Quantity>1</Quantity>
    </OrderLineItem>
    <OrderLineItem xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:ActivationLineItem" id="4">
      <Product>
        <Id>5340</Id>
        <Description>DUMMY</Description>
        <Domain>aaa</Domain>
      </Product>
      <Quantity>1</Quantity>
    </OrderLineItem>
    <OrderLineItem xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:DeactivationLineItem" id="12">
      <Product>
        <Id>53200</Id>
        <Description>DUMMY</Description>
        <Domain>ccc</Domain>
      </Product>
      <Quantity>21</Quantity>
    </OrderLineItem>
  </OrderLineItems>
</ns2:data>')

;WITH XMLNAMESPACES('http://mynamespace' AS ns)
SELECT
OrderLineItemID                = ref.value('@id', 'int')
,OrderLineItemParentID          = ref.value('@parentId', 'int')
,ProductID                      = NULLIF(ref.query('Product/Id').value('.', 'varchar(255)'),'')
,ProductDescription             = NULLIF(ref.query('Product/Description').value('.', 'varchar(255)'),'')
,ProductDomain                  = NULLIF(ref.query('Product/Domain').value('.', 'varchar(255)'),'')
,ProductAdditionalInfo          = NULLIF(ref.query('Product/AdditionalInfo').value('.', 'varchar(255)'),'')
,Quantity                       = ref.query('Quantity').value('.', 'int')

,LineItemType                   = ref.value('@xsi:type','varchar(max)')                 

FROM @tmp_xml t
    CROSS APPLY data.nodes('/ns:data/OrderLineItems/OrderLineItem') R(ref) 
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top