簡體   English   中英

在T-SQL查詢中,需要僅為根元素獲取屬性名稱 - 值對

[英]Need to get attribute name-value pairs for root element only, in T-SQL query

我已經創建了一個表值函數,它返回一個屬性名稱 - 值對的列表,當提供一個XML片段時,基於Ben Davis 在這里的出色響應。 它工作,但返回整個片段中所有屬性名稱 - 值對的列表,當我想將它限制在根元素上的那些時。 我怎樣才能做到這一點? 謝謝你,來自一個XQuery新手。

INSERT INTO @attributeList
SELECT DISTINCT
    CAST(attribute.name.query('local-name(.)') AS VARCHAR(100)),
    attribute.name.value('.','NVARCHAR(MAX)')
FROM @xml.nodes('//@*') attribute(name)

ETA:經過一些實驗證明,選擇器'node()/ @ *'可以工作。 感謝那些幫助過的人。

我在一個簡單的數據遷移應用程序或數據泵前端Sitecore中使用它。 我編寫了一個可以在.NET中使用POCO對象並將它們導入Sitecore的實用程序,但現在構建了一個遷移和日志記錄數據庫。 源對象作為XML存儲在一個位置。 再次感謝你。

這個問題已經在評論中得到了回答,所以這只是一個有點解釋的匯編。

對於實驗,我們將使用此XML:

DECLARE @XML XML =
'<root root_attr="0">
   <leaf leaf_attr="1">one</leaf>
   <brunch brunch_attr="2">
     <leaf leaf_attr="3">three</leaf>
   </brunch>
</root>';

我們需要提取根元素屬性的列表: root_attr="0"

有關XPath參考,請參閱MSDN XPath語法指南

因此,“/”代表“child”或“root node”如果出現在模式的開頭,“@”代表“attribute”,“*”代表“any”和“。”。 代表“當前背景”。 當然這應該給我們所有的根屬性:

SELECT
    CAST(attribute.name.query('local-name(.)') AS VARCHAR(MAX)) As [Name],
    attribute.name.value('.','NVARCHAR(MAX)') As [Value]
FROM @XML.nodes('/@*') attribute(name);

相反,它會給出錯誤: 不支持頂級屬性節點 XML中有兩種類型的節點 :< element >元素值</ element>和<element attribute =“Attribute Value”/>。 所以, /@*的XPath被解釋 XML的根的任何屬性,而不是根元素 事實上可以說明:

SELECT
    CAST(attribute.name.query('local-name(.)') AS VARCHAR(MAX)) As [Name],
    attribute.name.value('.','NVARCHAR(MAX)') As [Value]
FROM @XML.nodes('/') attribute(name);

返回:

Name Value
---- --------
     onethree

這是表示整個XML文檔的匿名節點。 '.' XPath會給出相同的結果。

好的,我們需要在XML文檔的根目錄中指定任何元素 如果此表達式不代表“遞歸下降”(所有子項),則該語法應為“//”(匿名根節點的子節點=根元素)。 確實

SELECT
    CAST(attribute.name.query('local-name(.)') AS VARCHAR(MAX)) As [Name],
    attribute.name.value('.','NVARCHAR(MAX)') As [Value]
FROM @XML.nodes('//@*') attribute(name);

返回所有元素的完整屬性列表:

Name        Value
----------- --------
root_attr   0
leaf_attr   1
brunch_attr 2
leaf_attr   3

好的,現在我們需要一種方式在XPath中說“root”“element”而不是“rootelement”,這顯然是一個保留字。 一種方法是擠入“any”,另一種方法 - 指定它應該是“node()”,除非我們知道根元素的實際名稱。

對於給定的XML,這三個是相等的:

SELECT
    CAST(attribute.name.query('local-name(.)') AS VARCHAR(MAX)) As [Name],
    attribute.name.value('.','NVARCHAR(MAX)') As [Value]
FROM @XML.nodes('/*/@*') attribute(name);

SELECT
    CAST(attribute.name.query('local-name(.)') AS VARCHAR(MAX)) As [Name],
    attribute.name.value('.','NVARCHAR(MAX)') As [Value]
FROM @XML.nodes('/node()/@*') attribute(name);

SELECT
    CAST(attribute.name.query('local-name(.)') AS VARCHAR(MAX)) As [Name],
    attribute.name.value('.','NVARCHAR(MAX)') As [Value]
FROM @XML.nodes('/root/@*') attribute(name);

返回:

Name      Value
--------- --------
root_attr 0

我們在那里。 一些XPath重言式解決“//”保留字。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM