it-swarm.dev

Existuje způsob, jak uniknout koncovému tokenu CDATA v xml?

Zajímalo by mě, jestli existuje nějaký způsob, jak uniknout z koncového tokenu CDATA (]]>) v sekci CDATA v dokumentu XML. Nebo obecněji, pokud existuje nějaká úniková posloupnost pro použití v rámci CDATA (ale pokud existuje, myslím, že by to asi mělo smysl jen tak uniknout žetonům začátku nebo konce). 

V zásadě můžete mít v CDATA začátek nebo konec tokenu a říct parseru, aby jej neinterpretoval, ale aby s ním zacházel jako s jinou sekvencí znaků.

Pravděpodobně byste měli pouze přepočítat strukturu xml nebo kód, pokud se to snažíte udělat, ale i když jsem s xml pracoval každý den po dobu posledních tří let a nikdy jsem neměl tento problém, Zajímalo by mě, jestli je to možné. Jen ze zvědavosti.

Upravit:

Jiné než použití html kódování ...

121

Je jasné, že tato otázka je čistě akademická. Naštěstí má velmi jednoznačnou odpověď.

Konec sekvence CDATA nelze uniknout. Výrobní pravidlo 20 XML specifikace je zcela jasné:

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

EDIT: Toto pravidlo produktu doslovně znamená "sekce CData může obsahovat cokoliv, čeho chcete BUT sekvenci"]]> '.

EDIT2: stejná sekce také čte:

V sekci CDATA je jako markup rozpoznán pouze řetězec CDEnd, takže se v jejich doslovné podobě mohou vyskytovat závorky levého úhlu a ampersandy; nepotřebují (a nemohou) uniknout pomocí "<" a "&". Sekce CDATA nemohou vnořit.

Jinými slovy, není možné použít odkaz entity, označení nebo jinou formu interpretované syntaxe. Jediný analyzovaný text v sekci CDATA je ]]> a ukončí sekci.

Není tedy možné uniknout ]]> v sekci CDATA.

EDIT3: stejná sekce také čte: 

2.7 Sekce CDATA

[Definice: Části CDATA se mohou vyskytovat kdekoli, kde se mohou vyskytnout znaková data; používají se k úniku bloků textu obsahujícího znaky, které by jinak byly rozpoznány jako značky. Sekce CDATA začínají řetězcem "<! [CDATA [" a končí řetězcem "]]>":] 

Pak může být sekce CDATA kdekoli, kde se mohou vyskytnout znaková data, včetně více sousedních sekcí CDATA umístěných v jediné sekci CDATA. To umožňuje rozdělení tokenu ]]> a jeho umístění do sousedních částí CDATA.

ex:

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

by měl být napsán jako

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

Musíte rozdělit svá data na kousky, abyste skryli ]]>.

Tady je celá věc:

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

První <![CDATA[]]]]>]]. Druhé <![CDATA[>]]>>.

165
S.Lott

Neuniknete ]]>, ale po > uniknete ]] vložením ]]><![CDATA[ před >, myslete na to stejně jako \ v řetězci C/Java/PHP/Perl, ale pouze před > a po ]].

MIMOCHODEM, 

S.Lottova odpověď je stejná jako tato, prostě formulovaná jinak.

15
Jason Pyeron

Odpověď S. Lotta je správná: koncovou značku nezakódujete, rozbijete ji v několika sekcích CDATA.

Jak spustit tento problém v reálném světě: pomocí editoru XML vytvořit dokument XML, který bude vložen do systému správy obsahu, zkuste napsat článek o sekcích CDATA. Váš obyčejný trik vkládání ukázek kódu do sekce CDATA vás zde nezdaří. Dokážete si představit, jak jsem se to naučil.

Ale za většiny okolností se s tím nesetkáte, a proto je důvod, proč: pokud chcete uložit text XML dokumentu jako obsah XML elementu, budete pravděpodobně používat metodu DOM, např .:

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

A DOM docela rozumně uniká <a>, což znamená, že jste v dokumentu neúmyslně vložili část CDATA.

A to je zajímavé:

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

Toto je pravděpodobně ideosyncrasy .NET DOM, ale to neznamená výjimku. Výjimka se dostane sem:

Console.Write(doc.OuterXml);

Hádám, že to, co se děje pod kapotou, je, že XmlDocument používá XmlWriter produkci jeho výstupu, a XmlWriter kontroluje, zda se dobře formuje, jak píše.

7
Robert Rossney

jednoduše ]]> nahraďte ]]]]><![CDATA[>

5
Thomas Grainger

Zde je další případ, kdy ]]> potřebuje uniknout. Předpokládejme, že potřebujeme uložit dokonale platný HTML dokument do CDATA bloku XML dokumentu a zdroj HTML se stane, že má svůj vlastní blok CDATA. Například:

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

komentovaná přípona CDATA musí být změněna na: 

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

protože analyzátor XML nebude vědět, jak zpracovávat bloky komentářů javascript

3
Shawn Becker

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

1
user2194495

Čistší způsob v PHP:

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

V případě potřeby nezapomeňte použít vícebajtové bezpečné umístění (non 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;
   }
1
Alain Tiemblo

Dalším řešením je nahradit ]]> podle ]]]><![CDATA[]>.

0
mik

Viz tato struktura:

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

Pro vnitřní CDATA tagy musíte zavřít ]]]]><![CDATA[> místo ]]>. Jednoduché.

0
Chad Kuehn