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

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

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

<node>This is a string</node>

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

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

Это неверно из-за &

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

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

Ответ 1

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

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

Действительно, вы должны использовать инструмент или библиотеку, которая пишет 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 не разрешены. Это также означает, что вызов, например, символьного объекта &#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...

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

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

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

< должен быть экранирован с помощью объекта &lt;, так как предполагается, что это начало тега.

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

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

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

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

Ответ 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, ""); 
}

Ответ 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 &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;

В С# используйте 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
"&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;"

Ответ 11

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

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

чтобы перевести все & -signs, которые не были изменены; к соответствующим.

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