Що є недійсними символами 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 є багато незаконних символів. Насправді навіть використання сутності символів для більшості контрольних символів призведе до помилки під час аналізу.
Thayne

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;особи - обов'язковий в атрибутах , визначених у одинарні лапки , але настійно рекомендується завжди уникнути.

The "Повинні бути екрановані з &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
доктор Макс Вьолкель,

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 шаблон регулярного вираження буде таким самим. І тоді ви можете використовувати метод, який називається substituAll, в класі String, який очікує шаблон регулярного вираження як параметр. Перевірте це: docs.oracle.com/javase/6/docs/api/java/lang/…
mathifonseca

2
У моєму рядку є такі недійсні символи: SUSITARIMO D & # x5; L DARBO SUTARTIES Цей код не видаляється & # x5; Тож документ xml не вдається ініціювати.
Дайній Крейвіс

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

17

Попередньо визначеними символами є:

& < > " '

Див. " Які особливі символи в XML? " Для отримання додаткової інформації.


Неправильно. Це не всі недійсні. Тільки & і <завжди недійсні в тексті.
rghome

7

На додаток до відповіді потаму, якщо ви хочете втекти, використовуючи блок CDATA.

Якщо ви помістите текст у блок CDATA, тоді вам не потрібно використовувати ескад . У цьому випадку ви можете використовувати всіх символів у наступному діапазоні :

графічне зображення можливих символів

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

Якщо є ще недійсні символи (наприклад, контрольні символи), то, ймовірно, краще використовувати якесь кодування (наприклад, base64).


3
Більше, ніж у блоці CDATA чи ні, деякі символи заборонені в XML.
долмен

4
точно, чи не це я написав? цитата: "всі символи в наступному діапазоні ". Під якими я маю на увазі лише символи в цьому конкретному діапазоні. Інші символи заборонені. - повністю згоден; але я не розумію голоси. - хоч ніяких важких почуттів.
bvdb

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

У процесорі 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");

Джерело звідси


-1

Хтось спробував це System.Security.SecurityElement.Escape(yourstring)? Це замінить недійсні символи XML у рядку з їх дійсним еквівалентом.


-5

Для XSL (в дуже ліниві дні) я використовую:

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

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

У нас є випадки, коли вхід знаходиться в CDATA, але система, яка використовує XML, не враховує його. Це неохайне виправлення, будьте обережні ...


8
Якщо це неохайно, чи справді це потрібно розмістити тут?
долмен
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.