XPath / XQuery를 사용하여 동일한 XML 요소의 모든 값을 연결


14

다음과 같은 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.

답변:


11

이것은 당신을 위해 일할 수 있습니다 :

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

text()첫 번째 R및 아래 에서 모든 요소를 선택합니다 .

당신이 원하는 모든 text()것을 할 수 있다면

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

값을 구분 I하고 J분리 하려면 대신하십시오.

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

마지막은 채팅에서 나에게 제안되었지만 첫 번째도 매우 도움이됩니다. XML 데이터를 다르게 생성하여 첫 번째 방법을 적용 할 수 있습니다.
Andriy M

7

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

바이올린을 참조하십시오


1
정말 좋습니다. 필요할 때마다 구분 기호를 포함하도록 쉽게 조정할 수 있습니다. 그리고 구분 기호가 있거나없는 문자열을 균일 한 방식으로 추출하려는 경우에 사용하기에는 너무 장황하지 않습니다.
Andriy M

0

요소와 값이 실제로 짧고 뚜렷한 경우 작동합니다.

declare @s varchar(99) = '<R><I>A</I><I>B</I><I>C</I></R>';

select
    @s,
    REPLACE(TRANSLATE ( @s, '<>I/R', '     '), ' ', '');

그러나 사소한 XML의 경우 어려움을 겪을 수 있습니다.


요소는 짧을 수 있지만 일반적으로 값은 다르며 요소 이름과 동일한 문자를 포함하지 않을 수도 있습니다. 그러나 상자 밖에서 접근 해 주셔서 감사합니다.
Andriy M
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.