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 डेटा को अलग तरह से जनरेट करने में सक्षम हो सकता हूं ताकि मैं इसे पहली विधि लागू कर सकूं।
एंड्री एम

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
यह सचमुच अच्छा है। जब भी मुझे आवश्यकता होती है, मैं आसानी से इसे शामिल कर सकता हूं। और यह भी इस्तेमाल होने वाली क्रिया नहीं है क्योंकि यह उस स्थिति में है जब मैं एक समान तरीके से और बिना सीमांकक के दोनों तारों को निकालना चाहता हूं।
एंड्री एम

0

यदि आपके तत्व और मूल्य वास्तव में कम हैं और यह काम अलग है:

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

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

गैर-तुच्छ XML के लिए, यह संघर्ष कर सकता है, हालांकि।


तत्व कम हो सकते हैं, लेकिन सामान्य रूप से मान नहीं होते हैं, और मुझे यकीन नहीं हो सकता है कि वे उसी वर्ण में नहीं होंगे जैसा कि तत्व नाम करते हैं। बॉक्स दृष्टिकोण के बाहर की सराहना करते हैं, हालांकि।
एंड्री एम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.