SQL सर्वर डाला जाता है जब XML संरचना बदल जाता है


15

मैं SQL सर्वर में XML स्तंभ के लिए कुछ XML डेटा सम्मिलित कर रहा हूं, लेकिन डेटा डाले जाने के बाद इसे sql सर्वर द्वारा बदल दिया गया है। यहां वह डेटा है जो मैं सम्मिलित करता हूं

              <xsl:value-of select="name/n/given" />
            <xsl:text> </xsl:text>
          <xsl:value-of select="name/n/family" />

जब मैंने इसे वापस पढ़ा, तो यह ऐसा दिखता है

              <xsl:value-of select="name/n/given" />
          <xsl:text />
          <xsl:value-of select="name/n/family" />

दूसरी पंक्ति पर ध्यान दें। यह एक समस्या है क्योंकि यह बदलता है कि XSLT परिवर्तन आउटपुट कैसे होगा। पहला उदाहरण दिए गए और परिवार के नाम के बीच एक स्थान बनाएगा, जबकि दूसरा कोई स्थान नहीं बनाएगा, इसलिए यह जॉन जॉन्सेन की तरह होगा, जबकि पहला जॉन जॉनसन की तरह होगा।

क्या इसे हल करने का कोई तरीका है?


यह एक समस्या है, क्योंकि इससे यह पता चलता है कि XSLT परिवर्तन आउटपुट कैसे होगा। पहली पंक्ति दिए गए और परिवार के नाम के बीच एक स्थान बनाएगी, जबकि दूसरी किसी के बीच कोई स्थान नहीं बनाएगी, इसलिए यह जॉन जॉन्सेन की तरह होगा, जबकि पहले वाला जॉन जॉन्सन की तरह होगा
मिस्टर

हम्म, उचित स्थान यह "" है, लेकिन इस टिप्पणी की तरह ही एक स्थान नहीं है (आप इसे नहीं देख सकते हैं)
a_vlad

1
शायद आप एक नियंत्रण वर्ण का उपयोग कर सकते हैं जो डेटा (जैसे _या ~) में मौजूद नहीं है और फिर प्रस्तुति समय पर उस स्थान को बदल दें।
हारून बर्ट्रेंड

जवाबों:


25

आप उन xml:space = "preserve"नोड्स पर उपयोग कर सकते हैं जहां आप स्थान रखना चाहते हैं। Xml का उपयोग करना: अंतरिक्ष "केवल आशय का संकेत है" लेकिन SQL सर्वर हमारे लिए यहां दयालु है।

एक नोड के लिए

declare @X xml =
'<root>
  <element xml:space = "preserve"> </element>
  <element> </element>
</root>'

select @X;

परिणाम:

<root>
  <element xml:space="preserve"> </element>
  <element />
</root>

संपूर्ण दस्तावेज:

declare @X xml =
'<root xml:space = "preserve">
  <element> </element>
  <element> </element>
</root>'

select @X;

परिणाम:

<root xml:space="preserve">
  <element> </element>
  <element> </element>
</root>

पूरे दस्तावेज़ के लिए एक और विकल्प शैली 1 के साथ कन्वर्ट का उपयोग करना है

महत्वहीन सफेद स्थान को संरक्षित करें। यह स्टाइल सेटिंग डिफ़ॉल्ट xml: space हैंडलिंग को xml के व्यवहार से मिलान करने के लिए सेट करती है: space = "preserve"।

declare @X xml = convert(xml, 
'<root>
  <element> </element>
  <element> </element>
</root>', 1)

select @X;

दिलचस्प है कि यह आवश्यक है। यह SQL सर्वर का रीटिट नहीं होना चाहिए यह तय करने के लिए कि व्हाट्सएप "महत्वहीन" है और चुपचाप इसे दस्तावेज़ संशोधनों के बिना पट्टी करें!
मोनिका

3
@LightnessRacesinOrbit SQL सर्वर द्वारा कार्यान्वयन से मैं काफी खुश हूँ। XML में फ़ॉर्मेटिंग (व्हाट्सएप) को तब तक महत्वपूर्ण नहीं माना जाता है जब तक आप कहते हैं कि यह नहीं है। इस उदाहरण पर एक नज़र डालें कि वास्तव में दस्तावेज़ में क्या नोड्स की संख्या है और यह भंडारण आकार के लिए क्या करता है ..
मिकेल एरिकसन

3
मैं इसे एक विशेष उल्लंघन मानता हूं, क्योंकि यहां डेटा को एक्सएमएल के रूप में स्वीकार किया जाता है और एक्सएमएल के रूप में संग्रहीत किया जाता है, बिना किसी हेरफेर या परिवर्तन या एक्सएमएल-लेयर शेननिगंस के किसी अन्य रूप के साथ केवल दस्तावेज़ को संग्रहीत करने के लिए (ओस्टेंसिक रूप से), इसलिए व्यवहार करना चाहिए एक "अनुप्रयोग" के बजाय एक "प्रोसेसर" में गिर जाते हैं, और इसलिए व्हाट्सएप को पट्टी नहीं करना चाहिए
मोनिका

9

SQL सर्वर दस्तावेज़ का यह पृष्ठ कहता है

डेटा को एक आंतरिक प्रतिनिधित्व में संग्रहीत किया जाता है जो ... पाठ XML की एक समान प्रतिलिपि नहीं हो सकता है, क्योंकि निम्न जानकारी को बरकरार नहीं रखा गया है: महत्वहीन सफेद स्थान, विशेषताओं का क्रम, नाम स्थान उपसर्ग और XML घोषणा।

आपके उदाहरण के लिए, मुझे लगता है कि यह मध्य टैग के सफेद स्थान को महत्वपूर्ण नहीं मानता है और इसलिए प्रतिनिधित्व को फिर से प्रस्तुत करने के लिए स्वतंत्र है। मुझे नहीं लगता कि इसके लिए कोई फिक्स है; यह है कि SQL सर्वर XML डेटा प्रकार को कैसे लागू करता है।

वर्क-अराउंड में सफेद स्थान के बजाय एक स्थान-धारक का उपयोग करना शामिल होगा जैसा कि @Aaron कहते हैं। उपभोक्ता को इन टोकन को सम्मिलित करना और बाहर निकालना याद रखना चाहिए। वैकल्पिक रूप से स्तंभ को XML के बजाय nvarchar के रूप में परिभाषित करें। यह निश्चित रूप से सभी सफेद स्थान और किसी भी अन्य स्वरूपण को संरक्षित करेगा। एक त्वरित उदाहरण:

create table x(i nvarchar(99), j xml);
insert x values ('<a> </a>', '<a> </a>');  -- note the space
select * from x

i           j
----------  -------
<a> </a>    <a />  

Nvarchar स्तंभ इनपुट प्रारूप को संरक्षित करता है, XML स्तंभ नहीं करता है।

आप SQL प्रश्नों में XPATH का उपयोग करने की क्षमता खो देंगे। यदि XML केवल अनुप्रयोग में छीनी जाती है तो यह सारहीन है। इसके अलावा अगर यह आपके लिए महत्वपूर्ण है, तो कैरेक्टर स्ट्रिंग को डीबी में सेविंग स्पेस दिया जा सकता है।


आप शायद अभी भी XML संस्करण के विरुद्ध क्वेरीज़ में XPATH का उपयोग कर सकते हैं, भले ही आपने इसे सुधारने दिया हो, जब तक कि आप वहाँ के महत्वहीन स्थान के लिए हिट (या मिस) पर भरोसा नहीं कर रहे हों।
हारून बर्ट्रेंड

0

CDATAडेटा संग्रहीत करते समय आप अपना स्थान लपेट सकते हैं :

<xsl:text><![CDATA[ ]]></xsl:text>

ऐसा प्रतीत होता है कि SQL सर्वर तब स्थान को आंतरिक रूप से रखता है, लेकिन CDATAपरिणाम का उपयोग करते समय अनावश्यक मार्कअप को हटा देता है SELECT। सौभाग्य से, इस तरह के परिणाम का फिर से उपयोग करते समय स्थान रखा जाता है SELECT:

DECLARE @X XML = '<text><![CDATA[ ]]></text>'
DECLARE @Y XML

SET @Y = (SELECT @X)

SELECT @Y

परिणाम होगा:

<text> </text>

सीडीएटीए की भी कोशिश की गई लेकिन उसे भी हटा दिया गया।
श्री

@MrZach CDATA स्वयं हटा दिया जाता है, लेकिन स्थान बना रहता है। (एसक्यूएल एक्सप्रेस 2016 पर कोशिश की गई।)
ब्रूनो

अजीब बात है, यहाँ जगह हटा दी गई थी। २०१६ या २०१ 2017 को भी सोचिए
मिस्टर ज़च २
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.