.NET XmlDocument LoadXML и сущности - PullRequest
4 голосов
/ 30 сентября 2008

При загрузке XML в XmlDocument, т.е.

XmlDocument document = new XmlDocument();
document.LoadXml(xmlData);

есть ли способ остановить процесс от замены сущностей? У меня странная проблема, когда у меня есть символ ТМ (хранится как сущность # 8482) в xml, который преобразуется в символ ТМ. Насколько я понимаю, этого не должно происходить, поскольку документ XML имеет кодировку ISO-8859-1 (в которой нет символа TM)

Спасибо

Ответы [ 7 ]

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

Это стандартное недопонимание набора инструментов XML. Весь бизнес с «& # x» - это синтаксическая функция, предназначенная для работы с кодировками символов. Ваш XmlDocument не является потоком символов - он освобожден от проблем кодировки символов - вместо этого он содержит абстрактную модель данных типа XML. Слова для этого включают DOM и InfoSet, я не уверен, что именно является точным.

"& # x" gubbins не будет существовать в этой модели, потому что вся проблема не имеет значения, он вернется - при необходимости - когда вы преобразуете информационный набор обратно в поток символов в некоторой конкретной кодировке.

Это недоразумение достаточно распространено, чтобы превратить его в академическую литературу как часть коллекции подобных причуд. Взгляните на «Xml Fever» в этом месте: http://doi.acm.org/10.1145/1364782.1364795

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

Для чего ты это пишешь? TextWriter? поток? что?

Следующая сущность сохраняет сущность (ну, она заменяет ее шестнадцатеричным эквивалентом) - но если вы делаете то же самое с StringWriter, он обнаруживает юникод и использует его вместо этого:

    XmlDocument doc = new XmlDocument();
    doc.LoadXml(@"<xml>&#8482;</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>&#x2122;</xml>
2 голосов
/ 30 сентября 2008

Признаюсь, что некоторые вещи немного запутаны с документами и кодировками XML, но я надеюсь, что они будут установлены при повторном сохранении, если вы все еще используете ISO-8859-1 - но если вы сохраните с UTF-8 это не нужно. В некотором смысле, логически документ действительно содержит символ, а не ссылку на сущность - последний является просто вопросом кодирования. (Я думаю здесь вслух - пожалуйста, не воспринимайте это как достоверную информацию.)

Что вы делаете с документом после его загрузки?

0 голосов
/ 30 сентября 2008

Спасибо за помощь.

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

0 голосов
/ 30 сентября 2008

& # xxxx; сущности считаются персонажем, которого они представляют. Весь XML преобразуется в юникод при чтении, и любые такие объекты удаляются в пользу символа юникода, который они представляют. Это включает в себя любое происшествие для них в источнике Юникода, например, строку, переданную в LoadXML.

Аналогично при записи любой символ, который не может быть представлен потоком, в который записывается, преобразуется в & # xxxx; юридическое лицо. Нет смысла пытаться их сохранить.

Распространенной ошибкой является ожидание получения String из DOM каким-либо способом, который использует кодировку, отличную от unicode. Это просто не происходит независимо от того, что

0 голосов
/ 30 сентября 2008

Ссылки на сущности не являются специфическими для кодировки. В соответствии с рекомендацией W3C XML 1.0 :

Если ссылка на символ начинается с "& # x", цифры и буквы до прекращение; обеспечить шестнадцатеричное представление код символа в ISO / IEC 10646.

0 голосов
/ 30 сентября 2008

Полагаю, если вы вложите содержимое сущности в раздел CDATA, оно должно оставить все в покое, например,

<root>
<testnode>
<![CDATA[some text &#8482;]]>
</testnode>
</root>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...