2012-12-20 14 views
6

में संस्थाओं डिकोडिंग मैं निम्नलिखित व्यवहार का सामना कर रहा हूँ:पीएचपी, SimpleXML, CDATA

$xml_string1 = "<person><name><![CDATA[ Someone&#039;s Name ]]></name></person>"; 
$xml_string2 = "<person><name> Someone&#039;s Name </name></person>"; 

$person = new SimpleXMLElement($xml_string1); 
print (string) $person->name; # Someone&#039;s Name 

$person = new SimpleXMLElement($xml_string2); 
print (string) $person->name; # Someone's Name 

$person = new SimpleXMLElement($xml_string1, LIBXML_NOCDATA); 
print (string) $person->name; # Someone&#039;s Name 

php डॉक्स का कहना है कि NOCDATA "मर्ज करें [s] पाठ नोड्स के रूप में CDATA"। मेरे लिए इसका मतलब है कि सीडीएटीए को तब टेक्स्ट नोड्स के समान माना जाएगा - या तीसरा उदाहरण का व्यवहार अब दूसरे उदाहरण के समान होगा।

मेरे पास एक्सएमएल (यह बाहरी स्रोत से फ़ीड है) पर नियंत्रण नहीं है, अन्यथा मैं केवल सीडीएटीए टैग को हटा दूंगा क्योंकि यह कुछ भी नहीं करता है और जो व्यवहार मैं चाहता हूं उसे खंडित करता हूं।

उपर्युक्त उदाहरण इस तरह से व्यवहार क्यों करता है? क्या SimpleXML को सीडीएटीए नोड्स को उसी तरह से संभालने का कोई तरीका है जिस तरह से यह टेक्स्ट नोड्स को संभालता है? "पाठ नोड्स के रूप में सीडीएटीए को मर्ज करें" वास्तव में क्या करता है, क्योंकि मुझे लगता है कि यह विकल्प समझ में नहीं आता है?

मैं डेटा खींचने के बाद वर्तमान में डिकोडिंग कर रहा हूं, लेकिन उपर्युक्त उदाहरण अभी भी मुझे समझ में नहीं आता है।

+0

'print' स्ट्रिंग संदर्भ है, तो आपको उस मामले में स्ट्रिंग करने के लिए डालने की जरूरत नहीं है। – hakre

+0

@ hakre लेकिन 'print' (अधिक सामान्य रूप से लिखे गए 'echo') को स्टैंड-इन के रूप में उपयोग करने की संभावना है, जबकि डीबगिंग के बाद कुछ और के साथ प्रतिस्थापित किया गया है, इसलिए मैं कहूंगा कि स्ट्रिंग-कास्टिंग को लगातार करने के लिए यह एक अच्छी आदत है बाद में भ्रम से बचें। – IMSoP

उत्तर

9

एक्सएमएल में CDATA भाग के प्रयोजन के पाठ का कोई खंड संपुटित करने के लिए है जो अन्यथा विशेष वर्ण की आवश्यकता होगी "जैसा है" (विशेष रूप से, >, < और &) भाग निकले किया जाना है। चरित्र & युक्त एक सीडीएटीए अनुभाग &amp; युक्त सामान्य टेक्स्ट नोड जैसा ही है।

एक पार्सर इस अनदेखी करने के लिए प्रदान करते हैं, और नाटक सभी CDATA नोड्स वास्तव में सिर्फ पाठ नोड्स थे, यह तुरंत जैसे ही कोई उल्लेख किया 'पी & हे परिभ्रमण "टूट जाएगा करना हो तो - & बस वहाँ पर नहीं हो सकता है कि इसका अपना (&amp;, या &somethingElse; के बजाए)।

LIBXML_NOCDATA क्योंकि (string)$foo बड़े करीने से एक साधारण पीएचपी स्ट्रिंग में पाठ और CDATA नोड्स के किसी भी क्रम को जोड़ती है, SimpleXML साथ सुंदर बेकार वास्तव में है। (कुछ लोग जो अक्सर नोटिस करने में विफल रहते हैं, क्योंकि print_r नहीं है।) यह डीओएम जैसे अधिक व्यवस्थित पहुंच विधियों के लिए जरूरी नहीं है, जहां आप टेक्स्ट नोड्स और सीडीएटीए नोड्स को अपने अधिकार में ऑब्जेक्ट्स के रूप में उपयोग कर सकते हैं।

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

$xml_string = "<person><name>Welcome aboard this <![CDATA[P&O Cruises]]> voyage!</name></person>"; 

$person = new SimpleXMLElement($xml_string); 
echo 'CDATA retained: ', $person->asXML(); 
// CDATA retained: <?xml version="1.0"?> 
// <person><name>Welcome aboard this <![CDATA[P&O Cruises]]> voyage!</name></person> 

$person = new SimpleXMLElement($xml_string, LIBXML_NOCDATA); 
echo 'CDATA merged: ', $person->asXML(); 
// CDATA merged: <?xml version="1.0"?> 
// <person><name>Welcome aboard this P&amp;O Cruises voyage!</name></person> 

, तो आप उस स्ट्रिंग और यह unescape लेने की जरूरत एक्सएमएल से पूरी तरह से स्वतंत्र। इस (खराब समझ पुस्तकालयों के साथ आलस्य को छोड़कर) ऐसा करने के लिए एक आम कारण कुछ एक XML दस्तावेज के अंदर सिर्फ किसी भी पुराने स्ट्रिंग के रूप में HTML में चिह्नित किया है, इस तरह के इलाज के लिए है:

<Comment> 
<SubmittedBy>IMSoP</SubmittedBy> 
<Text><![CDATA[I'm <em>really</em> bad at keeping my answers brief <tt>;)</tt>]]></Text> 
</Comment> 
+1

महान उत्तर, बहुत जानकारीपूर्ण –