Frage

Ich habe mich gefragt, ob es eine Möglichkeit ist eine CDATA End-Token (]]>) innerhalb eines CDATA-Abschnitts in einem XML-Dokument zu entkommen. Oder allgemeiner, wenn es eine Escape-Sequenz innerhalb eines CDATA für die Verwendung von (aber wenn es vorhanden ist, ich denke, es würde wahrscheinlich nur dann sinnvoll beginnen oder enden Token zu entkommen, sowieso).

Grundsätzlich können Sie haben ein beginnen oder Token in einem CDATA eingebettet beenden und den Parser sagen, es nicht zu interpretieren, sondern es als nur eine andere Zeichenfolge zu behandeln.

Wahrscheinlich sollten Sie nur Ihre XML-Struktur oder Ihren Code Refactoring, wenn Sie sich, das zu tun finden versuchen, aber obwohl ich auf einer täglichen Basis mit XML arbeiten seit den letzten 3 Jahren oder so und ich habe noch nie hatte dieses Problem, ich habe mich gefragt, ob es möglich war. Nur aus Neugier.

Edit:

Anders als HTML-Codierung ...

War es hilfreich?

Lösung

Natürlich ist diese Frage rein akademisch. Glücklicherweise hat es eine ganz bestimmte Antwort.

Sie können keine CDATA Endsequenz entkommen. Produktionsregel 20 der XML Spezifikation ist ganz klar:

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

EDIT: Diese Produktregel bedeutet wörtlich „ein CDATA-Abschnitt alles enthalten können Sie, aber die Reihenfolge wollen‚]]>‘keine Ausnahme..“

.

EDIT2: Der gleichen Abschnitt auch lautet:

  

Innerhalb eines CDATA-Abschnitt nur die CDEnd Zeichenfolge als Markup erkannt wird, so dass linke spitze Klammern und Et-Zeichen in ihrer wörtlichen Form auftreten können; sie brauchen nicht (und kann) werden mit „<“ und „&“ entkommen. CDATA-Abschnitte können nicht verschachtelt.

Mit anderen Worten, es ist nicht möglich Entitätsverweis, Markup oder jede andere Form von interpretiert Syntax zu verwenden. Der einzige geparsten Text in einem CDATA-Abschnitt ist ]]>, und es beendet den Abschnitt.

Es ist daher nicht möglich ]]> innerhalb eines CDATA-Abschnitts zu entkommen.

EDIT3: Der gleichen Abschnitt auch lautet:

  

2.7 CDATA Sections

     

[Definition: CDATA-Abschnitte können überall Zeichendaten auftreten können auftreten; sie werden verwendet, Textblöcke enthalten Zeichen zu entkommen, die andernfalls als Markup erkannt werden würde. CDATA-Abschnitte beginnen mit der Zeichenfolge "<[und enden mit der Zeichenfolge"] CDATA [] ">":]

Dann kann es einen CDATA-Abschnitt sein überall Zeichendaten auftreten können, darunter mehrere benachbarte CDATA Abschnitte inplace aus einem einzigen Abschnitt CDATA. Das erlaubt es möglich zu sein, den ]]> Token aufgeteilt und setzen Sie die beiden Teile davon in benachbarten CDATA-Abschnitte.

ex:

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

sollten geschrieben werden

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

Andere Tipps

Sie haben Ihre Daten in Stücke brechen die ]]> zu verbergen.

Hier ist die ganze Sache:

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

Der erste <![CDATA[]]]]> hat die ]]. Der zweite <![CDATA[>]]> hat die >.

Du hast nicht die ]]> entkommen, aber Sie > nach ]] entkommen, indem ]]><![CDATA[ vor dem > Einfügen, denken Sie an diesem wie ein \ in C / Java / PHP / Perl-String, sondern nur vor einem > und nach einem ]] benötigt.

BTW,

S.Lott Antwort ist das gleiche wie diese, nur anders formuliert.

S. Lott Antwort ist richtig. Sie das End-Tag nicht kodieren, können Sie es über mehrere CDATA Abschnitte brechen

Wie über dieses Problem in der realen Welt laufen: mit einem XML-Editor ein XML-Dokument zu erstellen, die in ein Content-Management-System eingespeist werden, versuchen Sie einen Artikel über CDATA-Abschnitte zu schreiben. Ihr gewöhnlicher Trick einzubetten Codebeispiele in einem CDATA-Abschnitt finden Sie hier scheitern. Sie können sich vorstellen, wie ich das gelernt.

Aber in den meisten Fällen, werden Sie dies nicht begegnen, und hier ist der Grund: Wenn man (sagen wir) den Text eines XML-Dokuments als den Inhalt eines XML-Elements speichern möchten, werden Sie wahrscheinlich ein DOM-Methode verwenden, zB:

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

Und der DOM ganz vernünftig entweicht die , was bedeutet, dass Sie nicht versehentlich einen CDATA-Abschnitt in Ihrem Dokument eingebettet haben.

Ach ja, und das ist interessant:

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

Dies ist wahrscheinlich eine ideosyncrasy von .NET DOM, aber das wirft keine Ausnahme. Die Ausnahme wird hier geworfen:

Console.Write(doc.OuterXml);

Ich würde vermuten, dass unter der Haube, was passiert ist, dass der XmlDocument verwendet ein XmlWriter seinen Ausgang und die XmlWriter Kontrollen für Wohlgeformtheits- wie es schreibt.

einfach ersetzen ]]> mit ]]]]><![CDATA[>

Hier ist ein weiterer Fall, in dem ]]> entkommen werden muss. Angenommen, wir ein perfekt gültiges HTML-Dokument in einem CDATA-Block eines XML-Dokuments speichern müssen und die HTML-Quelle passiert, es ist eigener CDATA-Block zu haben. Zum Beispiel:

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

die kommentierte CDATA Suffix geändert werden muss, um:

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

da ein XML-Parser wird nicht wissen, wie Sie JavaScript Kommentarblocks verarbeiten

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

Eine sauberere Art und Weise in PHP:

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

Vergessen Sie nicht, einen Multibyte-safe str_replace zu verwenden, wenn erforderlich (nicht latin1 $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;
   }

Eine andere Lösung ist ]]> durch ]]]><![CDATA[]> zu ersetzen.

Sehen Sie diese Struktur:

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

Für den inneren CDATA-Tag (e) Sie müssen mit ]]]]><![CDATA[> schließen statt ]]>. So einfach ist das.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top