Неверные символы в XML - PullRequest
       139

Неверные символы в XML

195 голосов
/ 08 апреля 2009

Я сейчас работаю с XML.

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

<node>This is a string</node>

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

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

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

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

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

Ответы [ 15 ]

182 голосов
/ 26 января 2015

Хорошо, давайте разделим вопрос о (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; - обязательно в атрибутах, определенных в двойных кавычках, но настоятельно рекомендуется всегда избегать его.

168 голосов
/ 24 февраля 2011

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

Char       ::=      #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]  /* any Unicode character, excluding the surrogate blocks, FFFE, and FFFF. */
128 голосов
/ 08 апреля 2009

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

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

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

57 голосов
/ 14 января 2013

Это код 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, ""); 
}
17 голосов
/ 08 апреля 2009

Предварительно объявленные символы:

& < > " '

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

7 голосов
/ 19 февраля 2014

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

WebUtility.HtmlEncode(stringWithStrangeChars)
5 голосов
/ 30 января 2017

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

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

graphical representation of possible characters

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

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

4 голосов
/ 20 февраля 2018

Другой способ удалить неправильные символы XML в C # с помощью XmlConvert.IsXmlChar Method (Доступно с .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.

2 голосов
/ 04 июля 2018

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

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

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

1 голос
/ 17 ноября 2016
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;"
...