Caractères invalides dans XML
je travaille actuellement avec du XML.
j'ai des noeuds qui tiennent des cordes comme ci-dessous:
<node>This is a string</node>
certaines des chaînes que je passe aux noeuds auront des caractères comme &, #, $ etc.
<node>This is a string & so is this</node>
ceci n'est pas valide en raison de la &
Je ne peux pas envelopper ces cordes en CDATA comme elles doivent l'être. J'ai essayé de chercher en ligne une liste de caractères qui ne peuvent pas être mettre dans les noeuds XML sans être dans un CDATA.
quelqu'un Pourrait-il m'indiquer la direction d'un ou de me fournir une liste des caractères illégaux?
14 réponses
les seuls caractères illégaux sont &
, <
et >
(ainsi que "
ou '
en attributs).
ils sont échappés en utilisant entités XML , dans ce cas vous voulez &
pour &
.
vraiment, cependant, vous devriez utiliser un outil ou une bibliothèque qui écrit XML pour vous et résume ce genre de chose loin pour vous afin que vous n'avez pas à vous soucier de cela.
la liste des caractères valides est 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. */
OK, séparons la question de (1) les caractères qui ne sont pas valides du tout dans un document XML, et (2) les caractères qui doivent être échappés:
la réponse fournie par @dolmen caractères invalides 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 personnages qui sont autorisés pour être inséré dans un document XML.
1.1. En XML 1.0
- référence: voir recommandation XML 1.0, §2.2 caractères
la liste globale des caractères autorisés est:
[2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF] /* any Unicode character, excluding the surrogate blocks, FFFE, and FFFF. */
fondamentalement, les caractères de contrôle et les caractères hors des gammes Unicode ne sont pas autorisés.
Cela signifie il est également interdit d'appeler par exemple l'entité de caractère 
.
1.2. En XML 1.1
- référence: voir recommandation XML 1.1, §2.2 caractères , et 1.3 justification et liste des changements pour le XML 1.1
la liste globale des caractères autorisés est:
[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 de sorte que les caractères de contrôle sont autorisés, et prend en compte une nouvelle révision de la norme Unicode, mais ceux-ci ne sont toujours pas autorisés: NUL (x00) , xFFFE , xFFFF ...
toutefois, l'utilisation de caractères de contrôle et de caractères Unicode non définis est décourager.
il est également à noter que tous les analyseurs ne tiennent pas toujours compte de ce fait et les documents XML avec des caractères de contrôle peuvent être rejetés.
2. Caractères qui doivent être échappés (pour obtenir un document bien formé):
Le <
faut l'échapper avec un <
entité, car il est supposé être le début d'une balise.
le &
doit être échappé avec un &
entité, puisqu'elle est censée être le début d'une entité référence
le >
doit être échappé avec l'entité >
. Il n'est pas obligatoire -- ça dépend du contexte, mais il est fortement recommandé de s'échapper.
le '
doit être échappé avec une entité '
-- obligatoire dans les attributs définis dans des guillemets simples, mais il est fortement conseillé de toujours s'en échapper.
le "
devrait être échappé avec une entité "
-- obligatoire dans les attributs définis dans les guillemets, mais il est fortement conseillé de toujours s'en échapper.
il s'agit d'un code C# pour supprimer les caractères invalides XML d'une chaîne de caractères et retourner une nouvelle chaîne de caractères 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, "");
}
une autre façon facile d'échapper aux caractères XML / XHTML indésirables dans C# est:
WebUtility.HtmlEncode(stringWithStrangeChars)
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" escapade 151950920". Dans ce cas, vous pouvez utiliser tous les caractères dans la gamme suivante :
Remarque: en plus de cela, vous n'êtes pas autorisé à utiliser le ]]>
séquence de caractères. Parce que ça correspondrait à la fin du bloc CDATA.
S'il y a encore des caractères invalides (par exemple des caractères de contrôle), alors il est probablement préférable d'utiliser une sorte d'encodage (par exemple base64).
Cette réponse a fonctionné pour moi
string code = Regex.Replace(item.Code, @"[\u0000-\u0008,\u000B,\u000C,\u000E-\u001F]", "");
détails dans ce lien au Blog
pour les gens de Java, Apache a une classe d'utilité (StringEscapeUtils) qui a une méthode d'aide escapeXml qui peut être utilisée pour échapper des caractères dans une chaîne en utilisant des entités XML.
dans le processeur XML de Woodstox, les caractères invalides 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
une autre façon de supprimer les caractères XML incorrects dans C# en utilisant XmlConvert.Méthode IsXmlChar (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 XML-valid.
public static bool CheckValidXmlChars(string content)
{
return content.All(ch => System.Xml.XmlConvert.IsXmlChar(ch));
}
. violon Net - https://dotnetfiddle.net/v1TNus
par exemple, le symbole d'onglet vertical (\v) n'est pas valide pour XML, il est valide UTF-8, mais pas valide XML 1.0, et même de nombreuses bibliothèques (y compris libxml2) le manquent et produisent en silence XML invalide.
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#, l'utilisation du Système.Sécurité.SecurityElement.Évasion ou système.Net.WebUtility.HtmlEncode pour échapper à ces personnages 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
"<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>"
Quelqu'un a essayé System.Security.SecurityElement.Escape(yourstring)
?
Ceci remplacera les caractères XML invalides dans une chaîne de caractères avec leur équivalent valide
Pour XSL (sur de très beaux jours) j'utilise:
capture="&(?!amp;)" capturereplace="&amp;"
de la traduction de tous les signes qui ne sont pas follwed på amp; bon.
nous avons des cas où L'entrée est en CDATA mais le système qui utilise le XML n'en tient pas compte. C'est une réparation bâclée, méfiez-vous...