Чтение XML с «&» в C # XMLDocument Object - PullRequest
18 голосов
/ 23 сентября 2008

Я унаследовал плохо написанное веб-приложение, в котором, похоже, возникают ошибки, когда оно пытается прочитать XML-документ, хранящийся в базе данных, в которой есть «&». Например, будет тег с содержанием: «Предоплата и оплата». Есть ли какая-то секретная простая вещь, чтобы не получить ошибку при разборе этого символа, или я упускаю что-то очевидное?

EDIT: Существуют ли какие-либо другие символы, которые приведут к тому же типу ошибки синтаксического анализатора из-за неправильной формы?

Ответы [ 6 ]

40 голосов
/ 23 сентября 2008

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

Prepaid & Charge

Я должен был решить ту же проблему раньше, и я сделал это с помощью этого регулярного выражения:

Regex badAmpersand = new Regex("&(?![a-zA-Z]{2,6};|#[0-9]{2,4};)");

Объедините это со строковой константой, определенной следующим образом:

const string goodAmpersand = "&";

Теперь вы можете просто сказать badAmpersand.Replace(<your input>, goodAmpersand);

Обратите внимание, что простой String.Replace("&", "&amp;") недостаточно хорош, поскольку вы не можете заранее знать для данного документа, будут ли какие-либо символы & правильно закодированы, неправильно или даже оба в одном и том же документе.

Подвох здесь в том, что вы должны сделать это с вашим xml-документом перед загрузкой его в ваш анализатор, что, вероятно, означает дополнительный проход через него. Кроме того, он не учитывает амперсанды внутри раздела CDATA. Наконец, only ловит амперсанды, а не другие нелегальные символы, такие как <. <strong>Обновление: на основе комментария, мне нужно обновить выражение и для сущностей с шестнадцатеричным кодом (& # x ...;).

Относительно того, какие символы могут вызвать проблемы, действительные правила немного сложны. Например, определенные символы допускаются в данных, но не в качестве первой буквы имени элемента. И нет простого списка нелегальных персонажей. Вместо этого большая (несмежная) полоса UNICODE определена как допустимая , и все, что находится за ее пределами, является незаконным.

Так что, когда дело доходит до этого, вы должны доверять источнику документа, чтобы иметь хотя бы определенную степень соответствия и согласованности. Например, я обнаружил, что люди часто достаточно умны, чтобы убедиться, что теги работают должным образом и убегают <, даже если они не знают, что & не разрешено, поэтому ваша проблема сегодня. Тем не менее, <strong>лучше всего исправить это в источнике.

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

4 голосов
/ 23 сентября 2008

Все остальные ответы верны, и я согласен с их советами, но позвольте мне добавить одну вещь:

ПОЖАЛУЙСТА, не создавайте приложения, которые работают с некорректно сформированным XML, это только усложняет остаток нашей жизни:).

Конечно, бывают случаи, когда у вас действительно просто нет выбора, если у вас нет контроля над другим концом, но вам действительно нужно, чтобы он выдавал фатальную ошибку и очень громко и недвусмысленно жаловался на то, что нарушается, когда такой происходит событие.

Вероятно, вы могли бы сделать еще один шаг и сказать: «Эй! Этот XML сломан в этих местах, и по этим причинам я попытался исправить его, чтобы сделать его правильно сформированным: ...».

Я не слишком знаком с API-интерфейсами MSXML, но большинство хороших синтаксических анализаторов XML позволяют устанавливать обработчики ошибок, чтобы вы могли перехватывать точное число строк / столбцов, где появляются ошибки, а также получать код ошибки и сообщение.

4 голосов
/ 23 сентября 2008

Веб-приложение не виновато, документ XML. Амперсанды в XML должны быть закодированы как &amp;. Невыполнение этого требования является синтаксической ошибкой.

Редактировать: в ответ на дополнительный вопрос, да, есть все виды подобных ошибок. Например, несбалансированные теги, некодированные знаки «меньше», значения атрибутов без кавычек, октеты вне кодировки символов и различные странности Unicode, нераспознанные ссылки на объекты и т. Д. Чтобы заставить любой порядочный XML-анализатор использовать документ, этот документ должен быть правильно сформирован. Спецификация XML требует, чтобы синтаксический анализатор, встречающийся с искаженным документом, выдавал фатальную ошибку.

3 голосов
/ 24 сентября 2008

Ваша база данных не содержит документов XML. Он содержит некоторые правильно сформированные XML-документы и некоторые строки, которые выглядят как XML для человека.

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

2 голосов
/ 23 сентября 2008

Существует несколько символов, из-за которых данные XML будут отображаться как неправильно сформированные.

Из w3schools :

Символы типа "<" и "&" недопустимы в элементах XML. </p>

Лучшее решение для ввода, которому нельзя доверять, чтобы быть XML-совместимым, - это обернуть его в теги CDATA, например

<![CDATA[This is my wonderful & great user text]]>

Все, что находится в тегах <![CDATA[ и ]]>, игнорируется анализатором.

2 голосов
/ 23 сентября 2008

Вы можете заменить & на &amp;

Или вы также можете использовать CDATA разделы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...