Caracteres no válidos en XML

Estoy trabajando con algunos XML en este momento.

Tengo nodos que tienen cadenas como a continuación:

This is a string 

Algunas de las cadenas que estoy pasando a los nodos tendrán caracteres como &, #, $, etc.

 This is a string & so is this 

Esto no es válido debido a la &

No puedo ajustar estas cadenas en CDATA porque deben ser como son. He intentado buscar en línea una lista de caracteres que no pueden colocarse en nodos XML sin estar en un CDATA.

¿Podría alguien dirigirme en la dirección de uno o proporcionarme una lista de personajes ilegales?

Los únicos caracteres ilegales son & , < y > (así como " o ' en los atributos).

Se han escapado usando entidades XML , en este caso, quiere & para & .

Realmente, sin embargo, debes usar una herramienta o biblioteca que escriba XML para ti y abstraiga este tipo de cosas para que no tengas que preocuparte por ello.

La lista de caracteres válidos está en la especificación XML :

 Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF] /* any Unicode character, excluding the surrogate blocks, FFFE, and FFFF. */ 

De acuerdo, separemos la pregunta de (1) los caracteres que no son válidos en ningún documento XML, y (2) los caracteres que deben escaparse:

La respuesta proporcionada por @dolmen Caracteres no válidos en XML sigue siendo válida, pero debe actualizarse con la especificación XML 1.1.

1. Caracteres no válidos

Los caracteres que se describen aquí son todos los caracteres que pueden insertarse en un documento XML.

1.1. En XML 1.0

  • Referencia: ver XML recomendación 1.0, §2.2 Personajes

La lista global de caracteres permitidos es:

[2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF] /* any Unicode character, excluding the surrogate blocks, FFFE, and FFFF. */

Básicamente, los caracteres de control y los caracteres fuera de los rangos Unicode no están permitidos. Esto significa también que se llama, por ejemplo, la entidad del personaje  está prohibido.

1.2. En XML 1.1

  • Referencia: ver la recomendación XML 1.1, §2.2 Caracteres , y 1.3 Justificación y lista de cambios para XML 1.1

La lista global de caracteres permitidos es:

[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 revisión de la recomendación XML ha ampliado los caracteres permitidos para que se permitan los caracteres de control, y tiene en cuenta una nueva revisión del estándar Unicode, pero estos aún no están permitidos: NUL (x00) , xFFFE , xFFFF

Sin embargo, se desaconseja el uso de caracteres de control y caracteres Unicode indefinidos.

También se puede observar que todos los analizadores no siempre tienen esto en cuenta y que los documentos XML con caracteres de control pueden ser rechazados.

2. Caracteres que necesitan ser escapados (para obtener un documento bien formado):

El < debe ser escapado con un < entidad, ya que se supone que es el comienzo de una etiqueta.

El & debe ser escapado con un & entidad, ya que se supone que es el comienzo de una referencia de entidad

El > debe ser escapado con > entidad. No es obligatorio, depende del contexto, pero se recomienda encarecidamente evitarlo.

El ' debe ser escapado con un ' entidad: obligatoria en los atributos definidos en comillas simples, pero se recomienda encarecidamente que siempre se escape.

El " debe ser escapado con una entidad" - obligatorio en los atributos definidos entre comillas dobles, pero se recomienda encarecidamente que siempre se escape.

Este es un código de C # para eliminar los caracteres inválidos XML de una cadena y devolver una nueva cadena válida.

 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, ""); } 

Los personajes predefinidos son:

 & < > " ' 

http://xml.silmaril.ie/specials.html

Otra forma fácil de escapar de caracteres XML / XHTML potencialmente no deseados en C # es:

 WebUtility.HtmlEncode(stringWithStrangeChars) 

Además de la respuesta de potame, si quieres escapar usando un bloque CDATA.

Si coloca su texto en un bloque CDATA, entonces no necesita usar el escape . En ese caso, puede usar todos los caracteres del siguiente rango :

representación gráfica de posibles caracteres

Nota: Además de eso, no está permitido usar la secuencia de caracteres ]]> . Porque coincidiría con el final del bloque CDATA.

Si todavía hay caracteres no válidos (por ejemplo, caracteres de control), entonces probablemente sea mejor usar algún tipo de encoding (por ejemplo, base64).

Esta respuesta funcionó para mí

 string code = Regex.Replace(item.Code, @"[\u0000-\u0008,\u000B,\u000C,\u000E-\u001F]", ""); 

Detalles en este enlace al Blog

Para la gente de Java, Apache tiene una clase de utilidad (StringEscapeUtils) que tiene un método de ayuda escapeXml que se puede usar para escanear caracteres en una cadena usando entidades XML.

En el procesador XML de Woodstox, los caracteres no válidos están clasificados 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"); 

Fuente de aquí

Otra forma de eliminar caracteres XML incorrectos en C # con el uso del método XmlConvert.IsXmlChar (disponible desde .NET Framework 4.0)

 public static string RemoveInvalidXmlChars(string content) { return new string(content.Where(ch => System.Xml.XmlConvert.IsXmlChar(ch)).ToArray()); } 

o puede verificar que todos los caracteres sean válidos para XML.

 public static bool CheckValidXmlChars(string content) { return content.All(ch => System.Xml.XmlConvert.IsXmlChar(ch)); } 

.Net Fiddle – https://dotnetfiddle.net/v1TNus

Por ejemplo, el símbolo de tabulación vertical (\ v) no es válido para XML, es válido UTF-8, pero no es válido XML 1.0, e incluso muchas bibliotecas (incluido libxml2) lo pasan por alto y emiten silenciosamente XML no vá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 > 

En C #, use System.Security.SecurityElement.Escape o System.Net.WebUtility.HtmlEncode para escapar de estos caracteres ilegales.

 string xml = "it's my \"node\" & i like it 0x12 x09 x0A 0x09 0x0A "; 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>" 

¿Alguien probó este System.Security.SecurityElement.Escape(yourstring) ? Esto reemplazará los caracteres XML no válidos en una cadena con su equivalente válido

Para XSL (en días realmente flojos) utilizo:

 capture="&(?!amp;)" capturereplace="&amp;" 

para traducir todos & -signs que no son seguidos på amp; a los adecuados.

Tenemos casos donde la entrada está en CDATA pero el sistema que usa el XML no lo toma en cuenta. Es una solución descuidada, ten cuidado …

    Intereting Posts