3

我想从 SELECT 语句中的“当前”节点读取 xsi:type 属性。我的 XML 如下所示:

 <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 tTEMP_XMLTABLE
CROSS APPLY xmlFile.nodes('/ns:data/OrderLineItems/OrderLineItem') R(ref) 

我的问题是 LineItemType 行,因为它引发错误:不支持 XQuery 语法 '@{http://www.w3.org/2001/XMLSchema-instance}:type'

这很奇怪,因为如果我不使用 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;

第二条语句适用于 SQL Server 2005。使用交叉应用时是否有可能读取 xsi:type 属性?

谢谢您的帮助

4

1 回答 1

1

这在 SQL Server 2008 SP1 中对我有用(您没有指定版本,所以我不确定这是否是您所拥有的)。不确定您是否可以将您的 xml 或您的 xml 副本放入一个无类型的 xml 字段中,就像我在这里一样,但这可能会帮助您解决我上面给您的链接中的模式绑定问题。

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) 
于 2012-01-24T14:35:57.493 回答