Ich habe mich gefragt, ob es eine Möglichkeit gibt, ein CDATA-End-Token ( ]]>
) in einem CDATA-Abschnitt in einem XML-Dokument zu umgehen. Oder allgemeiner, wenn es eine Escape-Sequenz für die Verwendung innerhalb einer CDATA gibt (aber wenn sie existiert, wäre es wahrscheinlich nur sinnvoll, Anfangs- oder End-Token zu maskieren).
Grundsätzlich können Sie ein Start- oder End-Token in eine CDATA einbetten und den Parser anweisen, es nicht zu interpretieren, sondern es nur als eine andere Zeichenfolge zu behandeln.
Wahrscheinlich sollten Sie einfach Ihre XML-Struktur oder Ihren Code umgestalten, wenn Sie dies versuchen, aber obwohl ich in den letzten 3 Jahren täglich mit XML gearbeitet habe und dieses Problem nie hatte, Ich habe mich gefragt, ob es möglich ist. Nur aus Neugier.
Bearbeiten:
Anders als die Verwendung von HTML-Codierung ...
>
wie>
in CData zu codieren, um sicherzustellen, dass Embedded]]>
nicht als CDEnd analysiert wird. Es bedeutet einfach, dass es unerwartet ist und dass&
ZUERST auch codiert werden muss,&
damit die Daten ordnungsgemäß decodiert werden können. Benutzer des Dokuments müssen wissen, dass sie auch diese CData dekodieren können. Dies ist nicht ungewöhnlich, da ein Teil des Zwecks von CData darin besteht, Inhalte zu enthalten, mit denen ein bestimmter Verbraucher umgehen kann. Es ist einfach nicht zu erwarten, dass eine solche CData von einem generischen Verbraucher richtig interpretiert wird.CDATA
wurde entwickelt, um alles zuzulassen : Sie werden verwendet, um Textblöcken zu entkommen, die Zeichen enthalten, die ansonsten als Markup erkannt würden. Dies impliziertCDATA
auch, da es sich auch um Markup handelt. Tatsächlich benötigen Sie jedoch nicht die von mir implizierte Doppelkodierung.]]>
ist ein akzeptables Mittel zum Codieren von aCDEnd
innerhalb von aCDATA
.Antworten:
Diese Frage ist eindeutig rein akademisch. Zum Glück hat es eine sehr eindeutige Antwort.
Sie können einer CDATA-Endsequenz nicht entkommen. Die Produktionsregel 20 der XML- Spezifikation ist ganz klar:
BEARBEITEN: Diese Produktregel bedeutet wörtlich "Ein CData-Abschnitt kann alles enthalten, was Sie wollen, ABER die Sequenz ']]>'. Keine Ausnahme.".
EDIT2: Der gleiche Abschnitt lautet auch:
Mit anderen Worten, es ist nicht möglich, Entitätsreferenzen, Markups oder andere Formen der interpretierten Syntax zu verwenden. Der einzige analysierte Text in einem CDATA-Abschnitt ist
]]>
und beendet den Abschnitt.Daher ist es nicht möglich,
]]>
innerhalb eines CDATA-Abschnitts zu entkommen .EDIT3: Der gleiche Abschnitt lautet auch:
Dann kann es überall dort, wo Zeichendaten auftreten können, einen CDATA-Abschnitt geben, einschließlich mehrerer benachbarter CDATA-Abschnitte anstelle eines einzelnen CDATA-Abschnitts. Auf diese Weise kann das
]]>
Token aufgeteilt und die beiden Teile in benachbarte CDATA-Abschnitte eingefügt werden.Ex:
sollte geschrieben werden als
quelle
<script>/*<![CDATA[*/javascript goes here/*]]>*/</script>
und mein Javascript enthält genau diese Sequenz! Ich mag die Idee, in mehrere CDATA-Abschnitte[[United States dollar|US$]]>100 million (2013)
die[[United States dollar|US$]]>100 million (2013)
der Leser und der Verfasser übersetzt haben, entschied sich für die Verwendung von CDATA, um dem Text zu entkommen, und schlug fehl.Sie müssen Ihre Daten in Teile zerlegen, um das zu verbergen
]]>
.Hier ist das Ganze:
<![CDATA[]]]]><![CDATA[>]]>
Der erste
<![CDATA[]]]]>
hat die]]
. Der zweite<![CDATA[>]]>
hat die>
.quelle
]]>
als]]]]><![CDATA[>
. 5 mal so lang ... wow. Aber dann ist es eine ungewöhnliche Sequenz.Sie haben nicht die entkommen ,
]]>
aber sie die entkommen ,>
nachdem]]
durch das Einfügen]]><![CDATA[
vor dem>
, denken Sie an diesen ebenso wie ein\
in C / Java / PHP / Perl - String , sondern nur vor einem benötigt>
und nach einem]]
.Übrigens,
Die Antwort von S.Lott ist dieselbe, nur anders formuliert.
quelle
]]]]><![CDATA[>
ist keine magische Sequenz für]]>
.]]]]>
hat]]
Zeichen als Daten und]]>
beendet den aktuellen CDATA-Abschnitt.<![CDATA[>
Startet einen neuen CDATA-Abschnitt und fügt>
ihn ein. Sie sind eigentlich zwei verschiedene Elemente und werden bei der Arbeit mit einem DOM-Parser unterschiedlich behandelt. Sie sollten sich dessen bewusst sein. Diese Vorgehensweise ist ähnlich]]]><![CDATA[]>
, außer dass]
die erste und]>
die zweite CDATA eingefügt werden. Der Unterschied bleibt bestehen.Die Antwort von S. Lott ist richtig: Sie codieren das End-Tag nicht, sondern teilen es in mehrere CDATA-Abschnitte auf.
So begegnen Sie diesem Problem in der realen Welt: Erstellen Sie mithilfe eines XML-Editors ein XML-Dokument, das in ein Content-Management-System eingespeist wird, und schreiben Sie einen Artikel über CDATA-Abschnitte. Ihr gewöhnlicher Trick, Codebeispiele in einen CDATA-Abschnitt einzubetten, schlägt hier fehl. Sie können sich vorstellen, wie ich das gelernt habe.
In den meisten Fällen tritt dies jedoch nicht auf, und hier ist der Grund: Wenn Sie den Text eines XML-Dokuments als Inhalt eines XML-Elements speichern (z. B.) möchten, verwenden Sie wahrscheinlich eine DOM-Methode, z.
Und das DOM entgeht dem <und> dem vernünftigerweise, was bedeutet, dass Sie nicht versehentlich einen CDATA-Abschnitt in Ihr Dokument eingebettet haben.
Oh, und das ist interessant:
Dies ist wahrscheinlich eine Ideosynkrasie des .NET-DOM, aber das löst keine Ausnahme aus. Die Ausnahme wird hier ausgelöst:
Ich würde vermuten, dass unter der Haube passiert, dass das XmlDocument einen XmlWriter verwendet, um seine Ausgabe zu erzeugen, und der XmlWriter beim Schreiben auf Wohlgeformtheit prüft.
quelle
ersetzen Sie einfach
]]>
mit]]]]><![CDATA[>
quelle
Hier ist ein weiterer Fall, in dem
]]>
entkommen muss. Angenommen, wir müssen ein perfekt gültiges HTML-Dokument in einem CDATA-Block eines XML-Dokuments speichern, und die HTML-Quelle verfügt zufällig über einen eigenen CDATA-Block. Beispielsweise:Das kommentierte CDATA-Suffix muss geändert werden in:
da ein XML-Parser nicht weiß, wie man mit Javascript-Kommentarblöcken umgeht
quelle
]]>
mit]]]]><![CDATA[>
noch hier gilt. Die Tatsache, dass es sich um JavaScript handelt oder kommentiert wird, ist nicht wichtig.In PHP:
'<![CDATA['.implode(explode(']]>', $string), ']]]]><![CDATA[>').']]>'
quelle
Ein sauberer Weg in PHP:
Vergessen Sie nicht, bei Bedarf einen multibyte-sicheren str_replace zu verwenden (nicht latin1
$string
):quelle
Ich denke nicht, dass es ein guter Weg ist, CDATA zu unterbrechen. Hier ist meine Alternative ...
Verwenden Sie diese Option
]
für die Escape-Sequenz, gefolgt vom Hex-Wert Ihres Charakters. Wie im&#xhhhh;
=>]<unicode value>;
Auf diese Weise wird, wenn Sie versuchen,
]]>
Ihre Codierung aufzuzeichnen, fn erzeugt,]005D;]005D;]003E;
was in CDATA in Ordnung ist.Es ist besser, als nach Entitätsnamen zu entkommen, da diese nicht jedes Mal in Ihrer App dekodiert werden und Sie möglicherweise andere Prioritäten für das Entkommen von Entitäten mit kaufmännischem Und haben als für das Entkommen anderer Zeichen / Sequenzen. Dadurch haben Sie mehr Kontrolle über den Inhalt von CDATA.
quelle
Siehe diese Struktur:
Für die inneren CDATA-Tags müssen Sie
]]]]><![CDATA[>
statt mit schließen]]>
. So einfach ist das.quelle