Sql-Server

使用 XPath/XQuery 連接同一 XML 元素的所有值

  • May 7, 2019

我有一個這樣的 XML 值:

<R>
 <I>A</I>
 <I>B</I>
 <I>C</I>
 ...
</R>

我想連接所有I值並將它們作為單個字元串返回:ABC....

現在我知道我可以分解 XML,將結果聚合為無節點 XML,然後應用於.values('text()[1]', ...)結果:

SELECT
 (
   SELECT
     n.n.value('text()[1]', 'varchar(50)') AS [text()]
   FROM
     @MyXml.nodes('/R/I') AS n (n)
   FOR XML
     PATH (''),
     TYPE
 ).value('text()[1]', 'varchar(50)')
;

但是,我只想使用 XPath/XQuery 方法來完成所有這些工作,如下所示:

SELECT @MyXml. ? ( ? );

有沒有這樣的方法?

我在這個方向尋找解決方案的原因是因為我的實際 XML 也包含其他元素,例如:

<R>
 <I>A</I>
 <I>B</I>
 <I>C</I>
 ...
 <J>X</J>
 <J>Y</J>
 <J>Z</J>
 ...
</R>

而且我希望能夠將I值提取為單個字元串並將J值提取為單個字元串,而不必為每個值使用笨拙的腳本​​。

這可能對您有用:

select @MyXml.value('/R[1]', 'varchar(50)')

text()它從第一個R和下面拾取所有元素。

如果你只想text()做你能做的一切

select @MyXml.value('.', 'varchar(50)')

如果您想要 forIJ分離的值,請改為執行此操作。

select @MyXml.query('/R/I/text()').value('.', 'varchar(50)'),
      @MyXml.query('/R/J/text()').value('.', 'varchar(50)')

根據您的實際 XML 結構,您可以考慮使用如下循環:

DECLARE @xml XML

SELECT @xml = '<R>
 <I>A</I>
 <I>B</I>
 <I>C</I>
 <J>X</J>
 <J>Y</J>
 <J>Z</J>
</R>'

SELECT 
   Tbl.Col.query('for $i in I return $i').value('.', 'nvarchar(max)'),
   Tbl.Col.query('for $i in J return $i').value('.', 'nvarchar(max)')
FROM @xml.nodes('R') Tbl(Col);

輸出這個:

(No column name) | (No column name) 
---------------  | --------------- 
ABC              | XYZ 

看到這個小提琴

引用自:https://dba.stackexchange.com/questions/237475