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


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

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

<node>This is a string</node>

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

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

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

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

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

14 178

14 ответов:

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

они сбежали с помощью XML entities в этом случае, если вы хотите &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. */

в принципе, управляющие символы и символы из диапазонов Юникода не допускаются. Это означает также, что вызов, например, символьной сущности &#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...

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

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

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

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

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

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

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

The " должен быть экранирован с &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, ""); 
}

предшествующие символы:

& < > " '

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, Apache имеет служебный класс (StringEscapeUtils), который имеет вспомогательный метод escapeXml, который может быть использован для экранирования символов в строке с помощью XML-сущностей.

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

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

еще один способ удалить неправильные символы 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

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

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

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

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

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

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