Що є недійсними символами 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.