2009-06-08 4 views
12

Ich erstelle XML-Dokumente mit Werten aus einer DB abgerufen. Gelegentlich wird aufgrund einer Legacy-Implementierung ein Wert zurückgegeben, der ein ungültiges Zeichen enthält, wenn es nicht ordnungsgemäß maskiert ist (z. B. &).Wann zu CDATA vs. Escape & Vice Versa?

Also die Frage wird, sollte ich CDATA oder Escape? Sind bestimmte Situationen füreinander besser geeignet?

Beispiele: hier

<Email>foo&[email protected]</Email> 

Ich würde in Richtung CDATA lehnen.

<Name>Bob & Tom</Name> 

Ich würde in Richtung Flucht hier neigen.

Ich möchte vermeiden, CDATA'ing jedes Mal blind, aber aus einer Performance-Perspektive scheint es, dass das die logische Wahl ist. Das ist immer schneller als nach einem ungültigen Zeichen zu suchen, und wenn es existiert, dann wrap.

Gedanken?

Antwort

16

CDATA ist in erster Linie nützlich, IMO, für die menschliche Lesbarkeit. Soweit es eine Maschine betrifft, gibt es keinen Unterschied zwischen CDATA und dem Text, außer der Länge, höchstens. Vielleicht wird die Escape-Version ein wenig länger dauern, aber ich sage vielleicht, weil dies kein signifikanter Faktor sein sollte, es sei denn, Ihre Anwendung ist größtenteils IO-gebunden.

Werden die Leute wahrscheinlich die XML lesen? Wenn nicht, lassen Sie einfach den XML-Parser das tun, was er tut, und machen Sie sich keine Sorgen über CDATA und maskierten Text. Wenn die Leute dieses XML lesen, dann könnte CDATA die bessere Wahl sein.

Wenn Sie ein XML-Element mit dem Wert XML haben, ist CDATA möglicherweise die bessere Wahl.

Weitere Informationen finden Sie zum Beispiel die Frage des XML-FAQ, When should I use a CDATA Marked Section?

+1

CDATA ist auch netzwerkfreundlich für größere Strings, die maskiert werden müssen, daher sollte IMO in den meisten Fällen verwendet werden, in denen die XML-Datei über ein Netzwerk übertragen wird. –

5

Ich habe Leute für die oben verwenden CDATA gesehen, die in Ordnung ist, und die Dinge für die Verpackung, die nicht XML - wie z.B. JSON oder CSS - und das ist ein besserer Grund, es zu benutzen. Das Problem tritt auf, wenn Benutzer Element-basierte Markups wie HTML zitieren und dann die Verwirrung entsteht.

Menschen nicht erwarten,

<![CDATA[<foo>bar</foo>]]> 

zu

&lt;foo&gt;bar&lt;/foo&gt; 

so weit identisch zu sein, wie XML-Systeme betroffen sind.

Siehe RSS-Tag-Suppe für Beispiele des Entsetzens von Flucht-Ebenen.

Sie müssen auch sicher sein, dass die Zeichenfolge ']]>' nie in Ihren umschlossenen Daten erscheint, da dies der Terminator ist.

Wenn also die Lesbarkeit nicht im Vordergrund steht oder Sie ein Nicht-Element-Markup umschließen, empfehle ich, CDATA zu vermeiden.

0

Umhüllen mit CDATA unter diesen Bedingungen: Wenn Sie zweifelhafte Daten haben und diese nicht erhalten möchten, verwenden Sie Daten werden für die Anzeige verwendet, weil diese App dann auch zu unescape geht. Escape wiederholt dasselbe Datenelement - mehr Anzahl der Parsing & Escape wird die Leistung beeinträchtigen.

0

Ich denke, dass es keinen wirklichen Unterschied gibt. Ich bevorzuge es, CDATA für alles zu verwenden, weil ich mich nicht um die Charaktere kümmern muss, um zu entkommen, und das Einzige, um das ich mich kümmern muss, sind die "]]>" im Inhalt, die beide erlaubt sind, wenn du die CDATA-Öffnung aufteilst und schließen Tags in mehrere Fragmente.

Beispiel (in PHP)

<?php 

function getXMLContent($content) 
{ 
    if 
    (
     (strpos($content, '<') !== false) || 
     (strpos($content, '>') !== false) || 
     (strpos($content, '&') !== false) || 
     (strpos($content, '"') !== false) || 
     (strpos($content, '\'') !== false) 
    ) 
    { 
     // If value contains ']]>', we need to break it into multiple CDATA tags 
     return "<![CDATA[". str_replace(']]>', ']]]]><![CDATA[>', $content) ."]]>"; 
    } 
    else 
    { 
     // Value does not contain any special characters which needs to be wrapped/encoded/escaped 
     return $content; 
    } 
} 

echo getXMLContent("Hello little world!"); 
echo PHP_EOL . PHP_EOL; 
echo getXMLContent("This <is> a & hard \" test ' for ]]> XML!"); 

?> 

Returns

Hello little world! 

<![CDATA[This <is> a & hard " test ' for ]]]]><![CDATA[> XML!]]> 

Wenn setzen Sie, dass wie diese in einer XML-Struktur:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<test> 
    <![CDATA[This <is> a & hard " test ' for ]]]]><![CDATA[> XML!]]> 
</test> 

... speichern es zu einer Datei (wie test.xml) und ope n mit einem Browser, werden Sie sehen, dass der Browser (oder eine beliebige andere XML-Anwendung/Parser) zeigt Ihnen die richtige ouput string:

This <is> a & hard " test ' for ]]> XML! 
0

Ich denke, CDATA wird schneller - es scannen muss für das Ende Zeichen, eine Kopie von Anfang bis Ende und übergibt das zurück - eine Kopie. Beim Lesen von maskierten Daten muss ein Puffer verwendet werden, der an es angehängt wird, wenn nach erkannten Zeichen gesucht wird, und wenn der Vorgang beendet ist, wird der Puffer in einen String umgewandelt und zurück übergeben. So wird das Entfliehen mehr Speicherplatz verbrauchen und Sie müssen eine zusätzliche Kopie erstellen. Obwohl Sie wahrscheinlich nur einen Unterschied in großen Datensätzen und hohe Anzahl von Transaktionen bemerken werden. Also, wenn es kleine Felder sind, mach dir keine Sorgen - benutze beides.