Недопустимые символы в XML
Я работаю с некоторыми XML на данный момент.
У меня есть узлы, которые содержат строки, как показано ниже:
<node>This is a string</node>
Некоторые из строк, которые я передаю узлам, будут иметь символы типа &, #, $и т.д.
<node>This is a string & so is this</node>
Это неверно из-за &
Я не могу обернуть эти строки в CDATA, поскольку они должны быть такими, какие они есть. Я пробовал смотреть в Интернете список символов, которые нельзя помещать в узлы XML, не будучи в CDATA.
Может ли кто-нибудь указать мне в сторону одного или предоставить мне список незаконных символов?
Ответы
Ответ 1
Единственными недопустимыми символами являются &
, <
и >
(а также "
или '
в атрибутах).
Они бежали с помощью XML-объектов, в этом случае вы хотите &
для &
.
Действительно, вы должны использовать инструмент или библиотеку, которая пишет XML для вас, и абстрагирует эту вещь для вас, поэтому вам не нужно беспокоиться об этом.
Ответ 2
Список допустимых символов находится в спецификации XML:
Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF] /* any Unicode character, excluding the surrogate blocks, FFFE, and FFFF. */
Ответ 3
ОК, разделите вопрос о (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 не разрешены.
Это также означает, что вызов, например, символьного объекта 
запрещен.
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...
Однако использование управляющих символов и undefined Unicode char не рекомендуется.
Также можно заметить, что все парсеры не всегда учитывают это, и документы XML с контрольными символами могут быть отклонены.
2. Символы, которые должны быть экранированы (для получения хорошо сформированного документа):
<
должен быть экранирован с помощью объекта <
, так как предполагается, что это начало тега.
&
должен быть экранирован с помощью объекта &
, так как предполагается, что это начало ссылки на сущность
>
должен быть экранирован с >
сущностью. Это не обязательно - это зависит от контекста, но настоятельно рекомендуется избегать его.
'
должен быть экранирован с объектом '
- обязательным для атрибутов, определенных в одинарных кавычках, но настоятельно рекомендуется всегда избегать его.
"
должен быть экранирован с объектом "
- обязательным для атрибутов, определенных в двойных кавычках, но настоятельно рекомендуется всегда избегать его.
Ответ 4
Это код С# для удаления недопустимых символов 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, "");
}
Ответ 5
Предполагаемые символы:
& < > " '
http://xml.silmaril.ie/specials.html
Ответ 6
Еще один простой способ избежать потенциально нежелательных символов XML/XHTML в С#:
WebUtility.HtmlEncode(stringWithStrangeChars)
Ответ 7
В дополнение к ответу на файл, если вы хотите сбежать с помощью блока CDATA.
Если вы помещаете текст в блок CDATA, вам не нужно использовать экранирование.
В этом случае вы можете использовать все символы в следующем диапазоне:
![графическое представление возможных символов]()
Примечание. Кроме того, вам не разрешается использовать последовательность символов ]]>
. Потому что это будет соответствовать концу блока CDATA.
Если имеются все еще недопустимые символы (например, управляющие символы), то, вероятно, лучше использовать какую-то кодировку (например, base64).
Ответ 8
Для людей Java Apache имеет класс утилиты (StringEscapeUtils), который имеет вспомогательный метод escapeXml, который может использоваться для экранирования символов в строке с использованием объектов XML.
Ответ 9
В процессоре 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");
Источник здесь
Ответ 10
ampersand (&) is escaped to &
double quotes (") are escaped to "
single quotes (') are escaped to '
less than (<) is escaped to <
greater than (>) is escaped to >
В С# используйте System.Security.SecurityElement.Escape или System.Net.WebUtility.HtmlEncode, чтобы избежать этих незаконных символов.
string xml = "<node>it 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>"
Ответ 11
Для XSL (в действительно ленивые дни) я использую:
capture="&(?!amp;)" capturereplace="&amp;"
чтобы перевести все & -signs, которые не были изменены; к соответствующим.
У нас есть случаи, когда ввод находится в CDATA, но система, использующая XML, не учитывает это. Это небрежное исправление, остерегайтесь...