Недопустимые символы в XML

на данный момент я работаю с некоторым XML.

у меня есть узлы, которые содержат строки, как показано ниже:

<node>This is a string</node>

некоторые строки, которые я передаю узлам, будут иметь такие символы, как&,#, $ и т. д.

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

это недопустимо из-за &

Я не могу обернуть эти строки в CDATA, поскольку они должны быть такими, какие они есть. Я попытался найти в интернете список символов, которые нельзя поместить в узлы XML, не находясь в Разделы CDATA.

может ли кто-нибудь указать мне в направлении одного или предоставить мне список незаконных символов?

14 ответов


только незаконные символы &, < и > (а также " или ' в атрибутах).

они сбежали, используя сущности XML в этом случае, если вы хотите &amp; на &.

на самом деле, хотя, вы должны использовать инструмент или библиотеку, которая пишет XML для вас и абстрагирует такого рода вещи для вас, так что вам не придется беспокоиться об этом.


список допустимых символов в спецификация XML:

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

хорошо, давайте разделим вопрос (1) символов, которые не являются допустимыми вообще в любом XML-документе, и (2) символов, которые должны быть экранированы:

ответ, предоставленный @dolmen недопустимые символы в XML по-прежнему действителен, но должен быть обновлен спецификацией XML 1.1.

1. Недопустимые символы

символы, описанные здесь, - это все символы, которые могут быть вставлены в XML документ.

1.1. В XML 1.0

глобальный список разрешенных символов:

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

в основном, контрольные символы и символы из диапазонов Unicode не допускаются. Это означает также, что вызов, например, сущности символа &#x3; запрещено.

1.2. в XML 1.1

глобальный список разрешенных символов:

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

эта редакция рекомендации XML расширила разрешенные символы, поэтому разрешены управляющие символы, и учитывает новую редакцию стандарт Unicode, но эти по-прежнему не разрешены:NUL (x00), xFFFE, xFFFF...

однако использование управляющих символов и неопределенного символа Unicode не рекомендуется.

также можно заметить, что все синтаксические анализаторы не всегда учитывают это, и XML-документы с контрольными символами могут быть отклонены.

2. Символы, которые необходимо экранировать (для получения хорошо сформированного документ):

на < должна начинаться с &lt; entity, так как предполагается, что это начало тега.

на & должна начинаться с &amp; сущность, так как предполагается, что это начало ссылки на сущность

на > следует избежать с &gt; сущности. Это не обязательно - это зависит от контекста, - но настоятельно рекомендуется избегать его.

на ' следует избежать с &apos; entity -- обязательно в атрибутах, определенных в одинарных кавычках, но настоятельно рекомендуется всегда избегать его.

на " следует избежать с &quot; entity -- обязательно в атрибутах, определенных в двойных кавычках, но настоятельно рекомендуется всегда избегать его.


это код C# для удаления недопустимых символов XML из строки и возврата новой допустимой строки.

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

символы predeclared являются:

& < > " '

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


еще один простой способ избежать потенциально нежелательных символов XML / XHTML в C#:

WebUtility.HtmlEncode(stringWithStrangeChars)

в дополнение к ответу potame, если вы хотите избежать использования блока CDATA.

Если вы поместите ваш текст в блоке CDATA вам не нужно использовать escaping. В этом случае вы можете использовать все символы в диапазоне:

graphical representation of possible characters

Примечание: кроме того, вы не можете использовать ]]> последовательность символов. Потому что это будет соответствовать концу CDATA блок.

Если все еще есть недопустимые символы (например, управляющие символы), то, вероятно, лучше использовать какую-то кодировку (например, base64).


этот ответ работал для меня

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

подробности в этой ссылка на блог


для Java folks Apache имеет класс утилиты (StringEscapeUtils), который имеет вспомогательный метод escapeXml, который может использоваться для экранирования символов в строке с использованием XML-сущностей.


в обработчике Woodstox XML недопустимые символы классифицируются этим кодом

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

источник здесь


другой способ удалить неправильные символы XML в C# с помощью XmlConvert.Метод IsXmlChar (доступно начиная с .NET Framework 4.0)

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

или вы можете проверить, что все символы XML-допустимы.

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

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

например, символ вертикальной вкладки (\v) недействителен для XML, он действителен UTF-8, но не действителен XML 1.0, и даже многие библиотеки (включая libxml2) пропускают его и молчаливый вывод недопустимого XML.


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;

в C# используйте System.Безопасность.SecurityElement.Побег или система.Сеть.WebUtility.HtmlEncode, чтобы избежать этих незаконных символов.

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

кто-нибудь пробовал этот System.Security.SecurityElement.Escape(yourstring)? Это заменит недопустимые символы XML в строке их действительным эквивалентом


для XSL (в очень ленивые дни) я использую:

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

перевести все & - знаки, которые не сопровождаются på amp; на правильные.

у нас есть случаи, когда вход находится в CDATA, но система, которая использует XML, не учитывает его. Это небрежное решение, будьте осторожны...