2012-01-24 27 views
3

我想從SELECT語句中的「當前」節點讀取xsi:type屬性。我的XML看起來是這樣的:從T-SQL中讀取xsi:type

<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> 

我的select語句如下所示:

;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」不支持

很奇怪,因爲我能讀一個單一類型的,如果我不使用交叉適用於:

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屬性?

感謝您的幫助

+1

[本文] [1]可能有一定的幫助...... [1]:http://stackoverflow.com/questions/2477237/how-to-select-the -sql-server-value-of-the-xsitype-attribute-in-sql-server – mwigdahl

+0

謝謝,但是這裏描述了我發佈的第二條sql語句。我需要閱讀CrossApply中的所有類型 – merror

+0

有趣的。什麼類型是「xmlFile」?如果我將它存儲在一個xml類型的變量中,我可以得到這個xml。 – mwigdahl

回答

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) 
+0

非常感謝,這工作!但我不能使用無類型的XML字段。是否有可能將它與一個類型化的XML(後面的XSD Schema)一起使用? – merror

+0

基於另一篇文章,我會說不。但是,您是否可以用計算列來擴充表格的模式,將您的類型化XML轉換爲非類型化,並將其用於類型提取?對於任何需要綁定模式的操作,仍然可以使用類型化的XML列。 – mwigdahl

+0

非常感謝。我現在對所有的值使用一個類型化的XML,並使用一個帶有非類型化XML列的tempTable來更新類型值。這不是很好,但它的工作原理;-) – merror