.NET XmlDocument LoadXML и сущности
Вопрос
При загрузке XML в XmlDocument, т.е.
XmlDocument document = new XmlDocument(); document.LoadXml(xmlData);
есть ли способ остановить процесс замены сущностей?У меня возникла странная проблема: символ TM (хранящийся как объект № 8482) в xml преобразуется в символ TM.Насколько я понимаю, этого не должно произойти, поскольку XML-документ имеет кодировку ISO-8859-1 (в которой нет символа TM).
Спасибо
Решение
Это стандартное непонимание набора инструментов XML.Вся эта история с «&#x» — это синтаксическая функция, предназначенная для работы с кодировками символов.Ваш XmlDocument не является потоком символов — он освобожден от проблем с кодировкой символов — вместо этого он содержит абстрактную модель данных типа XML.Слова для этого включают DOM и InfoSet, я не уверен, какое из них является точным.
Губбины "&#x" не будут существовать в этой модели, потому что вся проблема не имеет значения, они вернутся - если необходимо - когда вы преобразуете информационный набор обратно в поток символов в некоторой конкретной кодировке.
Это недоразумение настолько распространено, что вошло в академическую литературу как часть набора подобных причуд.Взгляните на «Xml Fever» по этому адресу: http://doi.acm.org/10.1145/1364782.1364795
Другие советы
Для чего ты это пишешь?Текстовый писатель?поток?что?
Следующее сохраняет объект (ну, он заменяет его шестнадцатеричным эквивалентом), но если вы делаете то же самое с StringWriter, он обнаруживает юникод и использует его вместо этого:
XmlDocument doc = new XmlDocument();
doc.LoadXml(@"<xml>™</xml>");
using (MemoryStream ms = new MemoryStream())
{
XmlWriterSettings settings = new XmlWriterSettings();
settings.Encoding = Encoding.GetEncoding("ISO-8859-1");
XmlWriter xw = XmlWriter.Create(ms, settings);
doc.Save(xw);
xw.Close();
Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray()));
}
Выходы:
<?xml version="1.0" encoding="iso-8859-1"?><xml>™</xml>
Признаюсь, с XML-документами и кодировками все становится немного запутанным, но я надеюсь, что они будут установлены соответствующим образом, когда вы снова сохраните их, если вы все еще используете ISO-8859-1 - но это если вы сохраните с UTF- 8, в этом нет необходимости.В каком-то смысле логически документ действительно содержит символ, а не ссылку на объект — последнее является всего лишь вопросом кодировки.(Здесь я размышляю вслух — пожалуйста, не воспринимайте это как авторитетную информацию.)
Что вы делаете с документом после его загрузки?
Я полагаю, что если вы поместите содержимое объекта в раздел CDATA, оно должно оставить все в покое, например.
<root>
<testnode>
<![CDATA[some text ™]]>
</testnode>
</root>
Ссылки на сущности не зависят от кодировки.Согласно Рекомендация W3C XML 1.0:
Если ссылка на символ начинается с "&#x", цифры и буквы до завершения;Предоставьте шестнадцатеричное представление кодовой точки персонажа в ISO/IEC 10646.
&#xxxx;сущности считаются персонажами, которых они представляют.Весь XML преобразуется в Юникод при чтении, и любые такие объекты удаляются в пользу символа Юникода, который они представляют.Сюда входит любое их появление в источнике Юникода, например строка, переданная в LoadXML.
Аналогично, при записи любого символа, который не может быть представлен записываемым потоком, он преобразуется в &#xxxx;сущность.Нет смысла пытаться их сохранить.
Распространенной ошибкой является ожидание получения строки из DOM каким-либо способом, использующим кодировку, отличную от Unicode.Этого просто не происходит, независимо от того, что
Спасибо за помощь.
Я исправил свою проблему, написав функцию HtmlEncode, которая фактически заменяет все символы перед их выводом на веб-страницу (вместо того, чтобы полагаться на несколько сломанную функцию HtmlEncode() .NET, которая, кажется, кодирует только небольшое подмножество символы нужны)