Caracteres inválidos no XML
eu tenho nós que seguram cordas como em baixo:
<node>This is a string</node>
Algumas das cadeias de caracteres que estou a passar para os nós terão caracteres como&,#, $ etc.
<node>This is a string & so is this</node>
isto não é válido devido ao &
Não posso embrulhar estas cordas em CDATA, porque têm de ser como são. Eu tentei procurar on-line para uma lista de caracteres que não podem ser colocados em nós XML sem estar em um CDATA. Alguém pode apontar-me a arma? direcção de um ou fornecer-me uma lista de personagens ilegais?14 answers
&
, <
e >
(assim como "
ou '
em atributos).
Eles escaparam usando entidades XML , neste caso você quer &
para &
.
Realmente, no entanto, você deve usar uma ferramenta ou biblioteca que escreve XML para você e abstrai este tipo de coisa para você, para que você não tenha que se preocupar com isso.
A lista de caracteres válidos está na especificação XML:
Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF] /* any Unicode character, excluding the surrogate blocks, FFFE, and FFFF. */
OK, vamos separar a questão de (1) os caracteres que não são válidos em nenhum documento XML, e (2) os caracteres que precisam ser escapados:
A resposta fornecida por @dolmen caracteres inválidos em XML ainda é válida, mas precisa de ser actualizada com a especificação XML 1.1.
1. Caracteres inválidos
Os caracteres aqui descritos são todos os caracteres que podem ser inseridos num documento XML.
1.1. Em XML 1.0
- referência: ver recomendação XML 1.0, §2.2 caracteres
A lista global de caracteres permitidos é:
[2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF] /* any Unicode character, excluding the surrogate blocks, FFFE, and FFFF. */
Basicamente, os caracteres de controlo e os caracteres fora dos intervalos Unicode não são permitidos.
Isto significa também que é proibido chamar, por exemplo, a entidade de carácter 
.
1.2. Em XML 1.1
- referência: ver recomendação XML 1.1, § 2.2 caracteres, e 1.3 fundamentação e lista de alterações para o XML 1.1
A lista global de caracteres permitidos é:
[2] Char ::= [#x1-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF] /* any Unicode character, excluding the surrogate blocks, FFFE, and FFFF. */
[2a] RestrictedChar ::= [#x1-#x8] | [#xB-#xC] | [#xE-#x1F] | [#x7F-#x84] | [#x86-#x9F]
Esta revisão do XML recomendação tem estendido os caracteres permitidos para o controle de caracteres são permitidos, e leva em conta uma nova revisão do padrão Unicode, mas estes ainda não estão permitidos : NUL (x00), xFFFE, xFFFF...
Contudo, a utilização of control characters and undefined Unicode char is discouraged.
Também se pode notar que todos os parsers nem sempre levam isto em conta e os documentos XML com caracteres de controlo podem ser rejeitados.
2. Caracteres que precisam ser escapados (para obter um documento bem formado):
A <
deve ser escapada com uma entidade <
, uma vez que se presume ser o início de uma etiqueta.
A &
deve ser escapada com uma entidade &
, uma vez que se presume ser o início de uma referência de entidade
A >
deve ser escapada com >
entidade. Não é obrigatório -- depende do contexto -- mas é fortemente aconselhável escapar.
A '
deve ser escapada com uma entidade '
-- obrigatória em atributos definidos entre aspas simples, mas é fortemente aconselhado a escapar sempre dela.
A "
deve ser escapada com uma entidade "
-- obrigatória em atributos definidos entre aspas duplas, mas é fortemente aconselhado para escapar sempre.
Este é um código C# Para remover os caracteres inválidos XML de um texto e devolver um novo texto válido.
public static string CleanInvalidXmlChars(string text)
{
// From xml spec valid chars:
// #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
// any Unicode character, excluding the surrogate blocks, FFFE, and FFFF.
string re = @"[^\x09\x0A\x0D\x20-\uD7FF\uE000-\uFFFD\u10000-\u10FFFF]";
return Regex.Replace(text, re, "");
}
Outra forma fácil de escapar a caracteres XML / XHTML potencialmente indesejados em C# é:
WebUtility.HtmlEncode(stringWithStrangeChars)
Além da resposta do potame, se quiser escapar usando um bloco CDATA.
Se colocar o seu texto num bloco CDATA, então não precisa de usar o escape {[[6]}. Nesse caso, pode usar todos os caracteres no seguinte intervalo:
Nota: Além disso, você não está autorizado a usar a sequência de caracteres ]]>
. Porque corresponderia ao fim do bloco CDATA.
Se ainda existirem caracteres inválidos (ex. caracteres de controle), então provavelmente é melhor usar algum tipo de codificação (por exemplo, base64).
string code = Regex.Replace(item.Code, @"[\u0000-\u0008,\u000B,\u000C,\u000E-\u001F]", "");
Detalhes neste link para o Blog
Para Java folks, o Apache tem uma classe de utilitários (StringEscapeUtils) que tem um método auxiliar escapeXml que pode ser usado para escapar caracteres em uma string usando entidades XML.
No processador XML Woodstox, os caracteres inválidos são classificados por este código
if (c == 0) {
throw new IOException("Invalid null character in text to output");
}
if (c < ' ' || (c >= 0x7F && c <= 0x9F)) {
String msg = "Invalid white space character (0x" + Integer.toHexString(c) + ") in text to output";
if (mXml11) {
msg += " (can only be output using character entity)";
}
throw new IOException(msg);
}
if (c > 0x10FFFF) {
throw new IOException("Illegal unicode character point (0x" + Integer.toHexString(c) + ") to output; max is 0x10FFFF as per RFC");
}
/*
* Surrogate pair in non-quotable (not text or attribute value) content, and non-unicode encoding (ISO-8859-x,
* Ascii)?
*/
if (c >= SURR1_FIRST && c <= SURR2_LAST) {
throw new IOException("Illegal surrogate pair -- can only be output via character entities, which are not allowed in this content");
}
throw new IOException("Invalid XML character (0x"+Integer.toHexString(c)+") in text to output");
Fonte de aqui
Outra forma de remover caracteres XML incorrectos em C# com a utilização de XmlConvert.Método IsXmlChar (disponível desde. NET Framework 4.0)
public static string RemoveInvalidXmlChars(string content)
{
return new string(content.Where(ch => System.Xml.XmlConvert.IsXmlChar(ch)).ToArray());
}
Ou pode verificar se todos os caracteres são válidos em XML.
public static bool CheckValidXmlChars(string content)
{
return content.All(ch => System.Xml.XmlConvert.IsXmlChar(ch));
}
. Net Fiddle - https://dotnetfiddle.net/v1TNus
Por exemplo, a vertical símbolo de tabulação (\v) não é válido para XML, é válido UTF-8, mas não é válido XML 1.0, e até mesmo muitas bibliotecas (incluindo libxml2) perdê-lo e, silenciosamente, saída XML inválido.
ampersand (&) is escaped to &
double quotes (") are escaped to "
single quotes (') are escaped to '
less than (<) is escaped to <
greater than (>) is escaped to >
Em C#, use o sistema.Seguranca.Segurança.Escape ou System. Net. WebUtility. HtmlEncode para escapar a estes caracteres ilegais.
string xml = "<node>it's my \"node\" & i like it 0x12 x09 x0A 0x09 0x0A <node>";
string encodedXml1 = System.Security.SecurityElement.Escape(xml);
string encodedXml2= System.Net.WebUtility.HtmlEncode(xml);
encodedXml1
"<node>it's my "node" & i like it 0x12 x09 x0A 0x09 0x0A <node>"
encodedXml2
"<node>it's my "node" & i like it 0x12 x09 x0A 0x09 0x0A <node>"
Para XSL (em dias realmente preguiçosos) eu uso:
capture="&(?!amp;)" capturereplace="&amp;"
Para traduzir todos os & - sinais que não são followed på amp; para os adequados.
Temos casos em que a entrada está em CDATA, mas o sistema que usa o XML não a leva em conta. É um arranjo desleixado, cuidado...