هل هناك طريقة للهروب عربون نهاية CDATA في أكس؟

StackOverflow https://stackoverflow.com/questions/223652

  •  03-07-2019
  •  | 
  •  

سؤال

وكنت أتساءل إذا كان هناك أي وسيلة للهروب عربون نهاية CDATA (]]>) داخل مقطع CDATA في مستند XML. أو بصورة أعم، إذا كان هناك بعض تسلسل هروب لاستخدام داخل CDATA (ولكن إذا كان موجودا، واعتقد انه سوف ربما يكون له معنى فقط للهروب بدء أو نهاية الرموز، على أي حال).

وفي الأساس، هل يمكن أن يكون تبدأ أو تنتهي رمز جزءا لا يتجزأ من CDATA ونقول للمحلل عدم تفسير ذلك، ولكن التعامل معها على أنها مجرد تسلسل حرف آخر.

وربما، يجب عليك فقط ريفاكتور هيكل أكس أو رمز الخاص بك إذا كنت تجد نفسك تحاول أن تفعل ذلك، ولكن على الرغم من أنني أعمل مع أكس على أساس يومي على مدى السنوات ال 3 الماضية أو نحو ذلك، ولقد كان أبدا هذه المشكلة، وأنا أتساءل عما إذا كان من الممكن. فقط من باب الفضول.

وتحرير:

وبخلاف باستخدام ترميز HTML ...

هل كانت مفيدة؟

المحلول

ومن الواضح أن هذا السؤال هو أكاديمي بحت. لحسن الحظ، كان لديه جواب واضح جدا.

ولا يمكنك الهروب تسلسل نهاية CDATA. حكم إنتاج 20 من XML مواصفات واضحة جدا:

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

وتحرير: هذه قاعدة الضرب تعني حرفيا "قد يحتوي الفرع ألف CDATA أي شيء تريده ولكن تسلسل ']]>' لا يوجد استثناء".

.

وEDIT2: إن نفس القسم يقرأ أيضا:

<اقتباس فقرة>   

وضمن قسم CDATA، فقط يتم التعرف على سلسلة CDEnd كما الترميز، بحيث أقواس زاوية اليسرى وقد تحدث في شكلها الحرفي الوات. فإنها لا تحتاج (ولا يمكن) أن هرب باستخدام "&lt;" و "&amp;". أقسام CDATA لا يمكن العش.

وبعبارة أخرى، فإنه ليس من الممكن استخدام مرجع الوحدة، الترميز أو أي شكل آخر من أشكال جملة تفسيرها. النص تحليل الوحيد داخل قسم CDATA هو ]]>، وينهي هذا الباب.

وبالتالي، فإنه ليس من الممكن للهروب ]]> داخل مقطع CDATA.

وEDIT3: إن نفس القسم يقرأ أيضا:

<اقتباس فقرة>   

2.7 أقسام CDATA

     

[التعريف: قد تحدث أقسام CDATA في أي مكان قد تحدث بيانات شخصية. فهي تستخدم للهروب كتل من حروف النص يحتوي التي لولاها يمكن التعرف على العلامات. تبدأ أقسام CDATA مع السلسلة "<[وتنتهي السلسلة"] CDATA []! ">":]

وبعد ذلك قد يكون هناك قسم CDATA قد تحدث بيانات شخصية في أي مكان، بما في ذلك عدة أقسام CDATA المجاورة inplace من قسم CDATA واحد. التي تسمح له أن يكون من الممكن تقسيم رمز ]]> ووضع شطري في أقسام CDATA المجاورة.

مثال:

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

ويجب أن يكتب

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

نصائح أخرى

لديك لكسر البيانات الخاصة بك إلى قطع لإخفاء ]]>.

وهنا كل شيء:

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

وو<![CDATA[]]]]> أولا ديه ]]. و<![CDATA[>]]> الثانية له >.

وأنت لا هربا من ]]> ولكن هل الهروب من > بعد ]] عن طريق إدراج ]]><![CDATA[ قبل >، فكر في هذا وكأنه \ في C / جافا / PHP سلسلة / بيرل ولكن يحتاج فقط قبل > وبعد ]].

وراجع للشغل،

والجواب S.Lott هي نفس هذا، فقط صيغت بشكل مختلف.

وS. الجواب لوت هو حق: لم يكن لترميز وسم النهاية، يمكنك كسرها عبر المقاطع CDATA متعددة

وكيفية تشغيل عبر هذه المشكلة في العالم الحقيقي: باستخدام محرر 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);

وهذا هو الأرجح ideosyncrasy من صافي DOM، ولكن هذا لا بطرح استثناء. يحصل طرح الاستثناء هنا:

Console.Write(doc.OuterXml);

وكنت أعتقد أن ما يحدث تحت غطاء محرك السيارة هو أن XmlDocument وباستخدام XmlWriter تنتج انتاجها، والشيكات XmlWriter للجيدا formedness كما يكتب.

وببساطة استبدال ]]> مع ]]]]><![CDATA[>

وهنا قضية أخرى التي ]]> يجب أن يكون لاذوا بالفرار. لنفترض أننا بحاجة إلى حفظ مستند HTML صحيحة تماما داخل كتلة CDATA وثيقة XML ومصدر HTML يحدث أن يكون ذلك من كتلة CDATA الخاصة. على سبيل المثال:

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

ولاحقة CDATA علق تحتاج إلى تغيير ل:

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

ومنذ محلل XML لن تعرف كيف تتعامل مع جافا سكريبت كتل تعليق

في PHP: '<![CDATA['.implode(explode(']]>', $string), ']]]]><![CDATA[>').']]>'

وهناك طريقة الأنظف في PHP:

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

لا تنس أن استخدام str_replace-متعددة البايت آمنة إذا لزم الأمر ($string غير LATIN1):

   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;
   }

وهناك حل آخر هو استبدال ]]> التي كتبها ]]]><![CDATA[]>.

وانظر هذا الهيكل:

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

لعلامة CDATA الداخلية (ق) يجب أن تقوم بإغلاق مع ]]]]><![CDATA[> بدلا من ]]>. البساطة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top