Eu queria saber se existe alguma maneira de escapar de um token final CDATA ( ]]>
) dentro de uma seção CDATA em um documento xml. Ou, de maneira mais geral, se houver alguma sequência de escape para uso em um CDATA (mas, se existir, acho que provavelmente só faria sentido escapar dos tokens iniciais ou finais).
Basicamente, você pode ter um token de início ou fim incorporado em um CDATA e dizer ao analisador para não interpretá-lo, mas tratá-lo como apenas mais uma sequência de caracteres.
Provavelmente, você deve refatorar sua estrutura xml ou seu código se tentar fazer isso, mas mesmo que eu trabalhe com xml diariamente nos últimos 3 anos ou mais e nunca tenha tido esse problema, Fiquei me perguntando se era possível. Apenas por curiosidade.
Editar:
Além de usar a codificação html ...
>
como>
no CData para garantir que o incorporado]]>
não seja analisado como CDEnd. Significa simplesmente que é inesperado e que também&
deve ser primeiro codificado&
para que os dados possam ser decodificados corretamente. Os usuários do documento também devem saber decodificar esse CData. Não é algo inédito, pois parte do objetivo do CData é conter o conteúdo que um consumidor específico entende como lidar. Não se pode esperar que esse CData seja interpretado adequadamente por qualquer consumidor genérico.CDATA
foi projetado para permitir qualquer coisa : eles são usados para escapar de blocos de texto contendo caracteres que, de outra forma, seriam reconhecidos como marcação IssoCDATA
também implica, já que também é marcação. Mas, na verdade, você não precisa da codificação dupla que eu impliquei.]]>
é um meio aceitável de codificar aCDEnd
dentro de aCDATA
.Respostas:
Claramente, esta questão é puramente acadêmica. Felizmente, tem uma resposta muito definida.
Você não pode escapar de uma sequência final CDATA. A regra de produção 20 da especificação XML é bastante clara:
EDIT: Esta regra do produto significa literalmente "Uma seção CData pode conter o que você deseja, mas a sequência ']]>'. Sem exceção.".
EDIT2: A mesma seção também lê:
Em outras palavras, não é possível usar referência de entidade, marcação ou qualquer outra forma de sintaxe interpretada. O único texto analisado dentro de uma seção CDATA é
]]>
e termina a seção.Portanto, não é possível escapar
]]>
dentro de uma seção CDATA.EDIT3: A mesma seção também lê:
Pode haver uma seção CDATA em qualquer lugar em que dados de caracteres possam ocorrer, incluindo várias seções CDATA adjacentes no lugar de uma única seção CDATA. Isso permite que seja possível dividir o
]]>
token e colocar as duas partes em seções CDATA adjacentes.ex:
deve ser escrito como
fonte
<script>/*<![CDATA[*/javascript goes here/*]]>*/</script>
e meu javascript inclui exatamente essa sequência! Eu gosto da idéia de dividir em várias seções CDATA ...[[United States dollar|US$]]>100 million (2013)
traduzido[[United States dollar|US$]]>100 million (2013)
pelo leitor e pelo escritor, optou por usar o CDATA para escapar do texto e falhou.Você precisa dividir seus dados em pedaços para ocultar o arquivo
]]>
.Aqui está a coisa toda:
<![CDATA[]]]]><![CDATA[>]]>
O primeiro
<![CDATA[]]]]>
tem o]]
. O segundo<![CDATA[>]]>
tem o>
.fonte
]]>
como]]]]><![CDATA[>
. 5 vezes o comprimento ... uau. Mas então, é uma sequência incomum.Você não escapa do,
]]>
mas escapa do>
depois]]
inserindo]]><![CDATA[
antes do>
, pense nisto como uma\
string C / Java / PHP / Perl, mas necessário apenas antes>
e depois de a]]
.BTW,
A resposta de S.Lott é a mesma, mas com palavras diferentes.
fonte
]]]]><![CDATA[>
não é uma sequência mágica para]]>
.]]]]>
possui]]
caracteres como dados e]]>
termina a seção CDATA atual.<![CDATA[>
inicia uma nova seção CDATA e a coloca>
. Na verdade, são dois elementos diferentes e serão tratados de maneira diferente ao trabalhar com um analisador DOM. Você deve estar ciente disso. Essa maneira de fazer isso é semelhante a]]]><![CDATA[]>
, exceto que coloca]
o primeiro e]>
o segundo CDATA. A diferença permanece.A resposta de S. Lott está certa: você não codifica a tag final, divide-a em várias seções CDATA.
Como enfrentar esse problema no mundo real: usando um editor XML para criar um documento XML que será alimentado em um sistema de gerenciamento de conteúdo, tente escrever um artigo sobre as seções CDATA. Seu truque comum de incorporar exemplos de código em uma seção CDATA falhará aqui. Você pode imaginar como eu aprendi isso.
Mas na maioria das circunstâncias, você não encontrará isso, e aqui está o porquê: se você deseja armazenar (digamos) o texto de um documento XML como o conteúdo de um elemento XML, provavelmente usará um método DOM, por exemplo:
E o DOM escapa razoavelmente do <e do>, o que significa que você não incorporou inadvertidamente uma seção CDATA ao seu documento.
Ah, e isso é interessante:
Provavelmente é uma ideosincrasia do .NET DOM, mas isso não gera uma exceção. A exceção é lançada aqui:
Eu acho que o que está acontecendo nos bastidores é que o XmlDocument está usando um XmlWriter produz sua saída, e o XmlWriter verifica se há boa formação durante a gravação.
fonte
simplesmente substitua
]]>
por]]]]><![CDATA[>
fonte
Aqui está outro caso em que
]]>
precisa ser escapado. Suponha que precisamos salvar um documento HTML perfeitamente válido dentro de um bloco CDATA de um documento XML e que a origem HTML possua seu próprio bloco CDATA. Por exemplo:o sufixo CDATA comentado precisa ser alterado para:
como um analisador XML não saberá como lidar com blocos de comentários javascript
fonte
]]>
por]]]]><![CDATA[>
ainda se aplica aqui. O fato de ser JavaScript ou comentar não é importante.Em PHP:
'<![CDATA['.implode(explode(']]>', $string), ']]]]><![CDATA[>').']]>'
fonte
Uma maneira mais limpa em PHP:
Não se esqueça de usar um str_replace multibyte-safe, se necessário (não latin1
$string
):fonte
Não acho que interromper o CDATA seja um bom caminho a percorrer. Aqui está a minha alternativa ...
Use
]
para a sequência de escape seguida pelo valor hexadecimal do seu personagem. Como no&#xhhhh;
=>]<unicode value>;
Dessa forma, se você tentar gravar
]]>
sua codificação, o fn produzirá o]005D;]005D;]003E;
que está correto no CDATA.É melhor do que escapar pelo nome da entidade, porque eles não são decodificados todas as vezes no seu aplicativo e você pode ter prioridades diferentes para escapar de entidades com e comercial e escapar de outros caracteres / seqüências. Como resultado, você tem mais controle sobre o conteúdo do CDATA.
fonte
Veja esta estrutura:
Para as tags CDATA internas, você deve fechar com em
]]]]><![CDATA[>
vez de]]>
. Simples assim.fonte