Что такое недопустимые символы в XML


229

Я работаю с некоторым XML, который содержит строки вроде:

<node>This is a string</node>

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

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

Это не действительно из-за &.

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

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


4
Любая уважительная причина не использовать CDATA?
— Петер Перхач

1
Да, я передаю строку в CMS с именем Fatwire, и узел с данными не может быть в CDATA, я не уверен, почему так работает Fatwire :(
— RailsSon

@Peter: Как я могу использовать CDATA в моем случае? stackoverflow.com/questions/6906705/…
— Радек

Ответы:


147

Единственными недопустимыми символами являются &, <и >(а также "или 'в атрибутах).

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

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


82
Некоторые элементы управления символов также не допускаются. Смотрите мой ответ ниже.
— дольмен

43
На самом деле это не совсем так. Ряд символов более низкого ascii также недопустим. Если вы попытаетесь записать 0x03 в документ Xml, вы получите ошибку, как правило, и если вам удастся правильно скрыть ее в документе XML, большинство зрителей будут жаловаться на недопустимый символ. Крайний случай, но это случается.
— Рик Страл

16
Этот ответ абсолютно неверен. Вот мое исключение XML с недопустимым символом 0x12 «System.Xml.XmlException:», шестнадцатеричное значение 0x12, недопустимый символ »
— Джордж

8
Это также неправильно в другом направлении; Наряду с пропуском каждого недопустимого символа, символы, которые он утверждает, являются незаконными, являются совершенно законными, хотя и имеют особое значение в контексте.
— Джон Ханна

6
В XML 1.0 есть много недопустимых символов. Фактически даже использование символьной сущности для большинства управляющих символов приведет к ошибке при разборе.
— Тейн

218

Хорошо, давайте разделим вопрос о персонажах, которые:

  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;лица, так как предполагается, что начало тега.

&Должны быть экранированы с &amp;лица, так как предполагается, что начало ссылки объект

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

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

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


171

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

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

7
Вы должны заметить, что хотя они и являются законными символами, & < > " 'в определенных контекстах их следует экранировать.
— Д.Шоули

7
«Законно» в данном контексте означает, что их окончательно декодированные значения являются законными, а не то, что они являются законными в потоке. Как указано выше, некоторые допустимые значения должны быть экранированы в потоке.
— SilverbackNet

У меня есть проблема, где 0x1c является недопустимым символом ... Ищет возможность в Java, как избежать этого ....
— basZero

Хороший обзор, какие символы действительны, а какие нет, можно найти здесь validchar.com/d/xml10/xml10_namestart
— Dr. Max Völkel

8
@xamde Этот список хорош, но он показывает только символы, которые можно использовать для запуска элемента XML. Проблема в том, какие символы допустимы в XML-файле в целом. Есть определенные символы, которые нигде не разрешены.
— Джон Сенчина

59

Это код 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, ""); 
}

6
Для Java шаблон регулярных выражений будет таким же. И тогда вы можете использовать метод replaceAll в классе String, который ожидает шаблон регулярного выражения в качестве параметра. Проверьте это: docs.oracle.com/javase/6/docs/api/java/lang/…
— mathifonseca

2
В моей строке есть такие недопустимые символы: SUSITARIMO D & # x5; L DARBO SUTARTIES Этот код не удаляет & # x5; Таким образом, XML-документ не может инициализироваться.
— Дайнюс Крейвис,

Я считаю, что вы не можете просто поместить этот шаблон в конструктор регулярных выражений .NET. Я не думаю, что он распознает \u10000и \u10FFFFкак отдельные символы, так как они требуют двух charэкземпляров utf-16 каждый, и, согласно документам, может быть не более 4 цифр. [\u10000-\u10FFFF]скорее всего , анализируются как [ \u1000, 0-\u10FF, F, F] , который является странным , но законно.
— GSerg


7

В дополнение к ответу Потаме, если вы хотите сбежать с помощью блока CDATA.

Если вы поместите свой текст в блок CDATA, вам не нужно использовать экранирование . В этом случае вы можете использовать все символы в следующем диапазоне :

графическое представление возможных символов

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

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


3
Есть ли в блоке CDATA или нет, некоторые символы запрещены в XML.
— дольмен

4
точно, разве это не то, что я написал? цитата: "все символы в следующем диапазоне ". Под этим я подразумеваю только персонажей в этом конкретном диапазоне. Другие персонажи не допускаются. - полностью согласен ; но я не понимаю, отрицательный голос. - никаких обид.
— 17

6

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

WebUtility.HtmlEncode(stringWithStrangeChars)

Неправильные персонажи
— дольмен

1
Он написал Xml не HTML.
— Эмануэле

6

Другой способ удаления неправильных символов 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

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


2

В итоге, допустимые символы в тексте:

  • табуляция, перевод строки и возврат каретки.
  • все неконтролируемые символы действительны, кроме & и <.
  • >не действует, если следующее ]].

Разделы 2.2 и 2.4 спецификации XML дают подробный ответ:

Персонажи

Юридическими символами являются табуляция, возврат каретки, перевод строки и юридические символы Unicode и ISO / IEC 10646.

Данные персонажа

Символ амперсанда (&) и левая угловая скобка (<) не должны появляться в их буквальной форме, за исключением случаев, когда они используются в качестве разделителей разметки или внутри комментария, инструкции обработки или раздела CDATA. Если они нужны где-то еще, их необходимо экранировать, используя либо числовые ссылки на символы, либо строки «&» и «<» соответственно. Правая угловая скобка (>) может быть представлена ​​с помощью строки ">" и для совместимости должна быть экранирована с использованием либо ">", либо ссылки на символ, когда она появляется в строке "]]>" в содержимом, когда это Строка не отмечает конец раздела CDATA.



1
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.Security.SecurityElement.Escapeили, System.Net.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;"

1

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


1

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

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

Источник отсюда


-1

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


-5

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

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

переводить все & -signs, которые не следуют за вами; к правильным.

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


8
Если это небрежно, действительно ли необходимо опубликовать это здесь?
— дольмен
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.