क्या xml में सीडीएटीए अंत टोकन से बचने का एक तरीका है?


129

मैं सोच रहा था कि क्या एक सीडीएमए अंत टोकन ( ]]>) एक सीडीएमए अनुभाग के भीतर एक एक्सएमएल दस्तावेज़ में बचने का कोई तरीका है । या, अधिक आम तौर पर, अगर सीडीएटीए के भीतर उपयोग करने के लिए कुछ बच निकलने का क्रम है (लेकिन अगर यह मौजूद है, तो मुझे लगता है कि यह संभवतया केवल प्रारंभ या अंत टोकन से बचने के लिए समझ में आएगा)।

मूल रूप से, क्या आपके पास सीडीएटीए में एक शुरुआत या अंत टोकन एम्बेडेड हो सकता है और पार्सर को इसकी व्याख्या नहीं करने के लिए कह सकता है लेकिन इसे सिर्फ एक अन्य चरित्र अनुक्रम के रूप में माना जा सकता है।

शायद, आपको अपनी xml संरचना या अपने कोड को फिर से रिफ्लेक्टर करना चाहिए यदि आप खुद को ऐसा करने की कोशिश करते हुए पाते हैं, लेकिन भले ही मैं पिछले 3 वर्षों से दैनिक आधार पर xml के साथ काम कर रहा हूं और मुझे यह समस्या कभी नहीं हुई, मैं सोच रहा था कि क्या यह संभव था। जिज्ञासा के कारण।

संपादित करें:

HTML एन्कोडिंग का उपयोग करने के अलावा ...


4
सबसे पहले, मैं उत्तर को सही लेकिन नोट के रूप में स्वीकार करता हूं: कुछ भी नहीं एन्कोडिंग से किसी को सीडीता के भीतर के >रूप में >यह सुनिश्चित करने के लिए ]]>कि सीडीईंड के रूप में पार्स नहीं किया जाएगा। इसका सीधा सा मतलब है कि यह अप्रत्याशित है और &इसे पहले भी एनकोड किया जाना चाहिए &ताकि डेटा को ठीक से डिकोड किया जा सके। दस्तावेज़ के उपयोगकर्ताओं को इस सीडीटा को भी डीकोड करना पता होना चाहिए। यह अनसुना नहीं है क्योंकि सीडीटा के उद्देश्य का हिस्सा ऐसी सामग्री है जिसमें एक विशिष्ट उपभोक्ता समझता है कि कैसे संभालना है। इस तरह की सीडीटा को किसी भी सामान्य उपभोक्ता द्वारा ठीक से व्याख्या किए जाने की उम्मीद नहीं की जा सकती है।
निक्स

1
@nix, CDATA केवल पाठ नोड सामग्री की घोषणा करने का एक स्पष्ट तरीका प्रदान करता है जैसे कि भाषा टोकन भीतर (अन्य के अलावा]>) पार्स नहीं किया जाता है। यह विशेष रूप से & gt; इस कारण से, एक सीडीएटीए ब्लॉक में, इसका मतलब है कि उन चार वर्णों का, न कि '>'। इसे परिप्रेक्ष्य में रखने के लिए: एक्सएमएल कल्पना में, सभी पाठ सामग्री को "सीडीटा" कहा जाता है, न कि केवल इन अनुक्रमों ("चरित्र डेटा") को। इसके अलावा यह विशिष्ट खपत एजेंटों के बारे में नहीं है। (ऐसी बात हालांकि मौजूद है - प्रसंस्करण निर्देश (<? लक्ष्य निर्देश?>)।
अर्धविराम

(मुझे जोड़ना चाहिए, भले ही इस तरह की बात नोड के मूल इरादे के विपरीत हो, सभी XML के साथ लंबी और यातनापूर्ण लड़ाई में उचित है। मुझे लगता है कि पाठकों के लिए यह जानना उपयोगी हो सकता है कि <!] [CDATA] ]]> वास्तव में उस उद्देश्य के लिए डिज़ाइन नहीं किया गया था।)
अर्धविराम

1
@ सेमिसोलोन CDATAको किसी भी चीज़ की अनुमति देने के लिए डिज़ाइन किया गया था : उनका उपयोग पाठ वाले ब्लॉकों से बचने के लिए किया जाता है, जिन्हें अन्यथा मार्कअप के रूप में मान्यता दी जाएगी, इसका मतलब CDATAयह भी है कि यह मार्कअप भी है। लेकिन, वास्तव में, आपको मेरे द्वारा निहित दोहरे एन्कोडिंग की आवश्यकता नहीं है। ]]&gt;एक के CDEndभीतर एन्कोडिंग का एक स्वीकार्य साधन है CDATA
निक्स

सच है, आपको डबल एन्कोडिंग की आवश्यकता नहीं होगी - लेकिन आपको अभी भी एजेंट को विशेष ज्ञान की आवश्यकता होगी, क्योंकि पार्सर पार्स नहीं करेगा & gt; as> हालांकि आपका क्या मतलब है, मुझे लगता है? पार्स करने के बाद आप उन्हें फिट होते हुए देख सकते हैं?
अर्धविराम

जवाबों:


141

स्पष्ट रूप से, यह प्रश्न विशुद्ध रूप से अकादमिक है। सौभाग्य से, इसका बहुत निश्चित उत्तर है।

आप एक CDATA अंत क्रम से बच नहीं सकते। XML विनिर्देश का उत्पादन नियम 20 बिल्कुल स्पष्ट है:

[20]    CData      ::=      (Char* - (Char* ']]>' Char*))

संपादित करें: इस उत्पाद के नियम का शाब्दिक अर्थ है "एक सीडीटा अनुभाग में कुछ भी हो सकता है जिसे आप अनुक्रम 'चाहते हैं]]>>" कोई अपवाद नहीं है। "।

EDIT2: एक ही खंड भी पढ़ता है:

CDATA अनुभाग के भीतर, केवल CDEnd स्ट्रिंग को मार्कअप के रूप में पहचाना जाता है, ताकि बाएं कोण कोष्ठक और ampersands उनके शाब्दिक रूप में हो सकें; उन्हें " &lt;" और " &amp;" के प्रयोग से नहीं (और नहीं) बच सकते हैं । CDATA अनुभाग घोंसला नहीं बना सकते हैं।

दूसरे शब्दों में, इकाई संदर्भ, मार्कअप या व्याख्या किए गए वाक्यविन्यास के किसी अन्य रूप का उपयोग करना संभव नहीं है। CDATA अनुभाग के अंदर केवल पार्स किया गया पाठ है ]]>, और यह अनुभाग को समाप्त करता है।

इसलिए, ]]>CDATA अनुभाग के भीतर बचना संभव नहीं है ।

EDIT3: एक ही खंड भी पढ़ता है:

2.7 CDATA अनुभाग

[परिभाषा: सीडीएटा सेक्शन कहीं भी हो सकता है, वर्ण डेटा हो सकता है; वे पाठ युक्त वर्णों के ब्लॉक से बचने के लिए उपयोग किए जाते हैं जिन्हें अन्यथा मार्कअप के रूप में पहचाना जाएगा। CDATA अनुभाग स्ट्रिंग से शुरू होता है "<! [CDATA [" और स्ट्रिंग के साथ समाप्त होता है "]]>":]

तब सीडीएटा अनुभाग हो सकता है कहीं भी चरित्र डेटा हो सकता है, जिसमें एकल सीडीएटा अनुभाग के कई आसन्न सीडीएटा अनुभाग शामिल हैं। यह ]]>टोकन को विभाजित करने और आसन्न CDATA वर्गों में इसके दो हिस्सों को रखने के लिए संभव बनाता है ।

उदाहरण के लिए:

<![CDATA[Certain tokens like ]]> can be difficult and <invalid>]]> 

के रूप में लिखा जाना चाहिए

<![CDATA[Certain tokens like ]]]]><![CDATA[> can be difficult and <valid>]]> 

1
वास्तव में। खैर, मैं एक अकादमिक प्रकार नहीं हूं, लेकिन जैसा कि मैंने सवाल में कहा है, मैं इस बारे में उत्सुक हूं। सच कहूं, तो मैं इस पर आपका शब्द ले लूंगा, क्योंकि मैं मुश्किल से नियम के लिए इस्तेमाल किए गए वाक्यविन्यास से समझ सकता हूं। आपके उत्तर के लिए धन्यवाद।
जुआन पाब्लो कैलिफोर्नो

39
यह एक अकादमिक प्रश्न नहीं है। एक ब्लॉग पोस्ट की RSS फ़ीड के बारे में सोचें जिसमें CDATA के बारे में चर्चा है।
यूएसआर

4
मेरा मतलब इस अर्थ में "अकादमिक" था: "चर्चा के लिए दिलचस्प, लेकिन व्यावहारिक उपयोग के बिना"। आम तौर पर, सीडीएटीए उपयोगी नहीं है, यह एक्सएमएल पाठ को क्रमबद्ध करने का एक तरीका है, और यह शब्दार्थ संस्थाओं और लेफ्टिनेंट का उपयोग करके विशेष वर्ण से बचने के लिए शब्दार्थ है; & gt; और & quot; वर्ण संस्थाएं सबसे सरल, सबसे मजबूत और सबसे सामान्य समाधान है, इसलिए CDATA अनुभागों के बजाय इसका उपयोग करें। यदि आप एक उचित XML लाइब्रेरी का उपयोग करते हैं (XML को स्ट्रिंग्स से बाहर बनाने के बजाय) तो आपको इसके बारे में सोचने की ज़रूरत नहीं है।
दादा

5
मैं सिर्फ इस एक से काट लिया गया क्योंकि मैं कुछ संकुचित जावास्क्रिप्ट को एक <script> टैग में एन्कोड करने की कोशिश कर रहा हूँ: <script>/*<![CDATA[*/javascript goes here/*]]>*/</script>और मेरी जावास्क्रिप्ट में बस यही क्रम शामिल है! मुझे कई
सीडीएटीए

3
मैंने वास्तविक दुनिया में इसका अनुभव किया। विकिपीडिया डंप को पढ़ने और एक और xml फ़ाइल लिखने के दौरान मुझे राष्ट्रीय परिवहन सुरक्षा बोर्ड के लिए इस पृष्ठ पर सामना करना पड़ा । इसमें इन्फोबॉक्स में बजट के लिए US $ 100 मिलियन (2013) था । स्रोत xml में निहित है [[United States dollar|US$]]&gt;100 million (2013)जो [[United States dollar|US$]]>100 million (2013)पाठक द्वारा अनुवादित किया गया था और लेखक ने पाठ से बचने के लिए CDATA का उपयोग करने का विकल्प चुना और असफल रहा।
पॉल जैक्सन

169

आपको अपने डेटा को छिपाने के लिए टुकड़ों में तोड़ना होगा ]]>

यहाँ पूरी बात है:

<![CDATA[]]]]><![CDATA[>]]>

पहले के <![CDATA[]]]]>पास है ]]। दूसरे के <![CDATA[>]]>पास है >


1
आपके उत्तर के लिए धन्यवाद। मैं एक बैकस्लैश समकक्ष (सी, पीएचपी, जावा, आदि में तार के भीतर) की तरह कुछ ढूंढ रहा था। डीडीए द्वारा उद्धृत नियम के अनुसार, ऐसा लगता है कि ऐसी कोई बात नहीं है।
जुआन पाब्लो कैलिफोर्नो

28
यह स्वीकृत उत्तर होना चाहिए। पलायन थोड़ा अस्पष्ट शब्द है, लेकिन यह उत्तर निश्चित रूप से भागने की भावना को संबोधित करता है । बहुत बुरा यह ओपी के भागने की संकीर्ण अवधारणा के लायक नहीं है , जो मनमाने ढंग से किसी कारण के लिए बैकस्लैश चरित्र को शामिल करने की आवश्यकता होती है।
G-Wiz

5
तो संक्षेप में, के ]]>रूप में बच ]]]]><![CDATA[>। लंबाई 5 गुना ... वाह। लेकिन फिर, यह एक असामान्य अनुक्रम है।
Brilliand

5
न केवल 5x लंबाई उल्लसित है, यह कोड में एक भी असामान्य अनुक्रम नहीं है, जो सीडीएटीए का मुख्य उपयोग मामला है! संपीड़ित जावास्क्रिप्ट को मानते हुए, जो रिक्त स्थान को हटाता है, आप सूचकांक द्वारा नामों की एक सरणी से नाम से एक क्षेत्र तक पहुंच सकते हैं, जैसे कि "अगर (फ़ील्ड [फ़ील्डनाम [0]]> 3)" और अब आपको इसे "अगर" में बदलना होगा फ़ील्ड [फ़ील्डनाम [0]]]> <! [CDATA [> 3) ", जो इसे और अधिक पठनीय बनाने के लिए CDATA के उपयोग के उद्देश्य को पराजित करता है, LOL। मैं मौखिक रूप से थप्पड़ मारना चाहूंगा जो कोई भी सीडीएटीए सिंटैक्स के साथ आया है।
त्रिवेंको

1
बचना, या अधिक सही ढंग से, उद्धृत करना, का अर्थ है कि संदर्भ में कच्चे पाठ का संदर्भ देने के बिना कुछ पाठ सम्मिलित करना। इसका बैकस्लैश से कोई लेना-देना नहीं है। और यह जवाब बच नहीं रहा है या उद्धृत नहीं है क्योंकि यह एक के बजाय दो सीडीएटीए अनुभाग पैदा करता है।
ddaa

17

आप बच नहीं है ]]>, लेकिन आप बच >के बाद ]]डालने से ]]><![CDATA[पहले >, बस एक तरह इस के बारे में सोच \सी / जावा / PHP / पर्ल स्ट्रिंग में, लेकिन एक से पहले ही जरूरत >है और एक के बाद ]]

Btw,

एस.लॉट का जवाब भी यही है, बस अलग-अलग शब्दों में।


2
मुझे यह शब्द पसंद है। :)
Brilliand

3
यह कहने का यह तरीका लोगों को गलत विचार देता है। यह बच नहीं रहा है। ]]]]><![CDATA[>के लिए कुछ जादुई अनुक्रम नहीं है ]]>। डेटा के रूप ]]]]>में ]]वर्ण हैं, और ]]>वर्तमान CDATA अनुभाग को समाप्त करता है। <![CDATA[>एक नया CDATA सेक्शन शुरू करता है और >उसमें डालता है। वे वास्तव में दो अलग-अलग तत्व हैं और डोम पार्सर के साथ काम करते समय अलग तरीके से व्यवहार किया जाएगा। आपको उसके बारे में पता होना चाहिए। इसे करने का यह तरीका समान है ]]]><![CDATA[]>, सिवाय इसके कि यह ]पहले और ]>दूसरे सीडीएटीए में डालता है । अंतर बना रहता है।
इदियाकापी

अंतर समाप्त हो गया है, क्योंकि CDATA सामग्री को बच गए पाठ के शाब्दिक काल के रूप में माना जाता है। केवल जब DOM के साथ खिलवाड़ होता है तो यह वास्तव में मायने रखता है, और उस स्तर पर आप अन्य अदृश्य सीमाओं के साथ वैसे भी काम कर रहे हैं जैसे पाठ, टिप्पणी और प्रसंस्करण निर्देश नोड।
बैजोर

7

एस। लोट का जवाब सही है: आप अंतिम टैग को सांकेतिक शब्दों में बदलना नहीं करते हैं, आप इसे कई सीडीएटीए वर्गों में तोड़ते हैं।

वास्तविक दुनिया में इस समस्या को कैसे चलाया जाए: XML संपादक का उपयोग करके XML दस्तावेज़ बनाने के लिए जो कि सामग्री-प्रबंधन प्रणाली में खिलाया जाएगा, CDATA अनुभागों के बारे में एक लेख लिखने का प्रयास करें। CDATA अनुभाग में कोड नमूने एम्बेड करने की आपकी साधारण ट्रिक आपको यहां विफल कर देगी। आप सोच सकते हैं कि मैंने यह कैसे सीखा।

लेकिन ज्यादातर परिस्थितियों में, आप इसका सामना नहीं करेंगे, और यहां बताया गया है: यदि आप XML दस्तावेज़ की सामग्री को XML तत्व की सामग्री के रूप में संग्रहीत (कहना) चाहते हैं, तो आप संभवतः DOM विधि का उपयोग करेंगे, उदा:

XmlElement elm = doc.CreateElement("foo");
elm.InnerText = "<[CDATA[[Is this a problem?]]>";

और DOM काफी यथोचित रूप से बच जाता है <और>, जिसका अर्थ है कि आपने अनजाने में अपने दस्तावेज़ में CDATA अनुभाग एम्बेड नहीं किया है।

ओह, और यह दिलचस्प है:

XmlDocument doc = new XmlDocument();

XmlElement elm = doc.CreateElement("doc");
doc.AppendChild(elm);

string data = "<![[CDATA[This is an embedded CDATA section]]>";
XmlCDataSection cdata = doc.CreateCDataSection(data);
elm.AppendChild(cdata);

यह शायद .NET DOM का एक ideosyncrasy है, लेकिन यह अपवाद नहीं है। अपवाद यहाँ फेंक दिया जाता है:

Console.Write(doc.OuterXml);

मुझे लगता है कि हुड के तहत क्या हो रहा है कि XmlDocument एक XmlWriter अपने उत्पादन का उपयोग कर रहा है, और XmlWriter अच्छी तरह से गठन के लिए जाँच करता है जैसा कि वह लिखता है।


खैर, मेरे पास लगभग "वास्तविक दुनिया" उदाहरण था। मैं आमतौर पर Xml को Flash से लोड करता हूं जिसमें CDATA सेक्शन के भीतर html मार्कअप होता है। इससे बचने का एक तरीका उपयोगी हो सकता है, मुझे लगता है। लेकिन वैसे भी, उस स्थिति में, सीडीएटीए सामग्री आमतौर पर वैध एक्सएचटीएमएल होती है, और इसलिए "बाहरी" सीडीएटीए से पूरी तरह बचा जा सकता है।
जुआन पाब्लो कैलिफ़ोर्निया

2
CDATA को लगभग हमेशा पूरी तरह से टाला जा सकता है। मुझे लगता है कि जो लोग सीडीएटीए के साथ संघर्ष करते हैं, वे अक्सर यह नहीं समझ पाते हैं कि वे वास्तव में क्या करने की कोशिश कर रहे हैं और / या वह तकनीक जो वे वास्तव में काम कर रहे हैं।
बजे रॉबर्ट रॉसनी

ओह, मुझे यह भी जोड़ना चाहिए कि सीडीएमएस मैं अपने जवाब में इस्तेमाल किए जाने वाले सीएमएसए का एकमात्र कारण यह था कि मैंने इसे लिखा था, और मुझे समझ नहीं आया कि मैं वास्तव में क्या करने की कोशिश कर रहा था और / या तकनीक कैसे काम करती है। मुझे CDATA का उपयोग करने की आवश्यकता नहीं थी।
बजे रॉबर्ट रॉसनी

यदि आप .net का उपयोग कर रहे हैं, तो सीडीएटीए के बारे में पूर्ववर्ती टिप्पणी टालने योग्य है - बस एक स्ट्रिंग के रूप में सामग्री लिखें और फ्रेमवर्क वास्तविक दुनिया से आपके लिए सभी भागने (और पढ़ने में असावधान) करेगा ...। ... xmlStream.WriteStartElement ("UnprocessedHtml"); xmlStream.WriteString (UnprocessedHtml); xmlStream.WriteEndElement ();
मार्क मुलिन


3

यहां एक और मामला है जिसमें ]]>बच निकलने की जरूरत है। मान लीजिए कि हमें एक XML दस्तावेज़ के CDATA ब्लॉक के अंदर एक पूरी तरह से मान्य HTML दस्तावेज़ को सहेजने की आवश्यकता है और HTML स्रोत का स्वयं का CDATA खंड होना आवश्यक है। उदाहरण के लिए:

<htmlSource><![CDATA[ 
    ... html ...
    <script type="text/javascript">
        /* <![CDATA[ */
        -- some working javascript --
        /* ]]> */
    </script>
    ... html ...
]]></htmlSource>

टिप्पणी की गई CDATA प्रत्यय को बदलने की आवश्यकता है:

        /* ]]]]><![CDATA[> *//

एक XML पार्सर के बाद से जावास्क्रिप्ट टिप्पणी ब्लॉक को संभालने के लिए कैसे पता नहीं चल रहा है


यह कोई विशेष मामला नहीं है। बस के ]]>साथ बदलें ]]]]><![CDATA[>अभी भी यहाँ लागू होता है। तथ्य यह है कि यह जावास्क्रिप्ट है, या टिप्पणी महत्वपूर्ण नहीं है।
थॉमस ग्रेिंगर


1

PHP में एक क्लीनर तरीका:

   function safeCData($string)
   {
      return '<![CDATA[' . str_replace(']]>', ']]]]><![CDATA[>', $string) . ']]>';
   }

यदि आवश्यक हो तो (गैर लैटिन 1) मल्टीबाइट-सुरक्षित str_replace का उपयोग करना न भूलें $string:

   function mb_str_replace($search, $replace, $subject, &$count = 0)
   {
      if (!is_array($subject))
      {
         $searches = is_array($search) ? array_values($search) : array ($search);
         $replacements = is_array($replace) ? array_values($replace) : array ($replace);
         $replacements = array_pad($replacements, count($searches), '');
         foreach ($searches as $key => $search)
         {
            $parts = mb_split(preg_quote($search), $subject);
            $count += count($parts) - 1;
            $subject = implode($replacements[$key], $parts);
         }
      }
      else
      {
         foreach ($subject as $key => $value)
         {
            $subject[$key] = mb_str_replace($search, $replace, $value, $count);
         }
      }
      return $subject;
   }

क्या आप अपने पतन की व्याख्या कर सकते हैं? यह कहना कि मैंने एक गलती की, यह समझाने में उतना उपयोगी नहीं है कि यह कहाँ है।
एलेन टिंबलो

यदि आप यूटीएफ -8 का उपयोग कर रहे हैं, तो मल्टीबीट सुरक्षित प्रतिस्थापन करने की आवश्यकता नहीं है। मैं हालांकि नीचे नहीं गया था :)
frodeborli

-1

मुझे नहीं लगता कि सीडीएटीए को बाधित करना बेहतर तरीका है। यहाँ मेरा विकल्प है ...

]अपने चरित्र के हेक्स मूल्य के बाद भागने के क्रम के लिए उपयोग करें । जैसे &#xhhhh;=> में]<unicode value>;

इस तरह से यदि आप ]]>अपने सांकेतिक शब्दों में बदलने की कोशिश करते हैं तो सीडीएटीए में ]005D;]005D;]003E;जो ठीक है वह उत्पन्न होगा ।

यह इकाई नाम से बचने से बेहतर है, क्योंकि वे आपके ऐप में हर बार डिकोड नहीं होते हैं और आपके पास एम्परसेंड बनाम कुछ अन्य वर्ण / अनुक्रम से बचने वाली संस्थाओं से बचने के लिए अलग-अलग प्राथमिकताएं हो सकती हैं। परिणामस्वरूप आपके पास CDATA की सामग्री पर अधिक नियंत्रण है।


-2

इस संरचना को देखें:

<![CDATA[
   <![CDATA[
      <div>Hello World</div>
   ]]]]><![CDATA[>
]]>

आंतरिक CDATA टैग के लिए आपको ]]]]><![CDATA[>इसके स्थान पर बंद होना चाहिए ]]>। इतना ही आसान।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.