web-dev-qa-db-fra.com

Caractères invalides en XML

Je travaille avec du XML pour le moment.

J'ai des nœuds qui contiennent des chaînes comme ci-dessous:

<node>This is a string</node>

Certaines des chaînes que je passe aux nœuds auront des caractères tels que &, #, $ etc.

<node>This is a string & so is this</node>

Ce n'est pas valide en raison de la &

Je ne peux pas envelopper ces chaînes dans CDATA, car elles doivent être comme elles sont. J'ai essayé de chercher en ligne une liste de caractères qui ne peuvent être placés dans des nœuds XML sans être dans un CDATA.

Quelqu'un pourrait-il m'indiquer quelqu'un ou me fournir une liste de personnages illégaux?

188
RailsSon

Les seuls caractères interdits sont &, < et > (ainsi que " ou ' dans les attributs).

Ils se sont échappés en utilisant Entités XML , dans ce cas, vous voulez &amp; pour &.

En réalité, vous devriez utiliser un outil ou une bibliothèque qui écrit du XML pour vous et qui résume ce genre de choses pour vous afin de ne pas vous inquiéter.

127
Welbog

OK, séparons la question de (1) les caractères qui ne sont pas valables du tout dans un document XML et (2) les caractères qui doivent être échappés:

La réponse fournie par @dolmen Caractères non valides en XML est toujours valide, mais doit être mise à jour avec la spécification XML 1.1.

1. Caractères invalides

Les caractères décrits ici sont tous les caractères pouvant être insérés dans un document XML.

1.1. En XML 1.0

La liste globale des caractères autorisés est la suivante:

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

En principe, les caractères de contrôle et les caractères situés en dehors des plages Unicode ne sont pas autorisés . Cela signifie également que l'appel par exemple de l'entité caractère &#x3; est interdit.

1.2. En XML 1.1

La liste globale des caractères autorisés est la suivante:

[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]

Cette révision de la recommandation XML a étendu les caractères autorisés afin que les caractères de contrôle soient autorisés et prend en compte une nouvelle révision de la norme Unicode, mais celles-ci ne sont toujours pas autorisées: NUL (x00), xFFFE, xFFFF ...

Toutefois, l'utilisation de caractères de contrôle et de caractères Unicode non définis est déconseillée.

On peut également noter que tous les analyseurs ne prennent pas toujours cela en compte et que les documents XML avec des caractères de contrôle peuvent être rejetés.

2. Caractères à échapper (pour obtenir un document bien formé):

Le < doit être échappé avec une entité &lt;, car il est supposé être le début d'une balise.

& doit être échappé avec une entité &amp;, car il est supposé être le début d'une référence d'entité

Le > doit être échappé avec l'entité &gt;. Ce n’est pas obligatoire - cela dépend du contexte - mais il est vivement conseillé de l’échapper.

Le ' doit être échappé avec une entité &apos; - obligatoire dans les attributs définis entre guillemets simples, mais il est vivement conseillé de toujours l'échapper.

Le " doit être échappé avec une entité &quot; - obligatoire dans les attributs définis entre guillemets doubles, mais il est vivement conseillé de toujours y échapper.

174
potame

La liste des caractères valides se trouve dans la spécification XML ​​ :

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

Il s'agit d'un code C # permettant de supprimer les caractères XML non valides d'une chaîne et de renvoyer une nouvelle chaîne valide.

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

Les caractères prédéclarés sont:

& < > " '

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

17
cgp

Un autre moyen simple d'échapper aux caractères XML/XHTML potentiellement indésirables en C # est le suivant:

WebUtility.HtmlEncode(stringWithStrangeChars)
7
tiands

En plus de la réponse de potame, si vous voulez vous échapper en utilisant un bloc CDATA.

Si vous mettez votre texte dans un bloc CDATA, vous n'avez pas besoin d'utiliser l'échappement . Dans ce cas, vous pouvez utiliser tous les caractères de la plage suivante:

 graphical representation of possible characters

Remarque: De plus, vous n'êtes pas autorisé à utiliser la séquence de caractères ]]>. Elle correspondrait à la fin du bloc CDATA.

S'il existe encore des caractères non valides (par exemple, des caractères de contrôle), il est probablement préférable d'utiliser un type de codage (par exemple, base64).

4
bvdb

Cette réponse a fonctionné pour moi

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

Détails dans ce lien vers Blog

2
Kalpesh Popat

Une autre façon de supprimer les caractères XML incorrects dans C # à l’aide de XmlConvert.IsXmlChar, méthode (Disponible depuis .NET Framework 4.0)

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

ou vous pouvez vérifier que tous les caractères sont valides en XML.

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

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

Par exemple, le symbole de tabulation verticale (\ v) n'est pas valide pour XML, il est valide pour UTF-8, mais pas pour XML 1.0, et même de nombreuses bibliothèques (y compris libxml2) ne l'utilisent pas et produisent en mode silencieux un XML non valide.

2
Alex Vazhev

Dans le processeur XML Woodstox, les caractères non valides sont classés par ce code

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

Source de ici

1
Jerome Saint-Yves

Pour les personnes Java, Apache a une classe d’utilitaire (StringEscapeUtils) qui a une méthode d’assistance escapeXml qui peut être utilisée pour échapper des caractères dans une chaîne en utilisant des entités XML.

1
A Null Pointer

En résumé, les caractères valides dans le texte sont:

  • onglet, saut de ligne et retour de chariot;
  • tous les caractères de non-contrôle sont valides sauf & et <;
  • > n'est pas valide si suivant]].

Les sections 2.2 et 2.4 de la spécification XML apportent une réponse détaillée:

Personnages

Les caractères légaux sont les tabulations, les retours à la ligne, les sauts de ligne et les caractères légaux de Unicode et ISO/IEC 10646

Données de caractère

Le caractère esperluette (&) et le crochet angulaire gauche (<) ne doivent pas apparaissent sous leur forme littérale, sauf lorsqu'ils sont utilisés comme délimiteurs de balisage, ou dans un commentaire, une instruction de traitement ou une section CDATA. Si ils sont nécessaires ailleurs, ils doivent être échappés en utilisant soit numérique références de caractères ou les chaînes "&" et "<" respectivement. La parenthèse à angle droit (>) peut être représentée à l’aide de La chaîne ">" et doit, pour des raisons de compatibilité, être échappée à l'aide de ">" ou une référence de caractère lorsqu'elle apparaît dans la chaîne "]]> " dans le contenu, lorsque cette chaîne ne marque pas la fin d'un CDATA section.

0
rghome
ampersand (&) is escaped to &amp;

double quotes (") are escaped to &quot;

single quotes (') are escaped to &apos; 

less than (<) is escaped to &lt; 

greater than (>) is escaped to &gt;

En C #, utilisez System.Security.SecurityElement.Escape ou System.Net.WebUtility.HtmlEncode pour échapper à ces caractères illégaux.

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
"&lt;node&gt;it&apos;s my &quot;node&quot; &amp; i like it 0x12 x09 x0A  0x09 0x0A &lt;node&gt;"

encodedXml2
"&lt;node&gt;it&#39;s my &quot;node&quot; &amp; i like it 0x12 x09 x0A  0x09 0x0A &lt;node&gt;"
0
live-love

Quiconque a essayé cette System.Security.SecurityElement.Escape(yourstring)? Cela remplacera les caractères XML invalides dans une chaîne par leur équivalent

0
klaydze