Как сохранить XML без экранирования символов? - PullRequest
4 голосов
/ 15 февраля 2012

В моем приложении C # данные XML могут содержать произвольный текст элемента, который уже был предварительно обработан, так что (среди прочего) недопустимые символы были преобразованы в их экранированную (закодированную сущность символа xml).

Пример: <myElement>this & that</myElement> был преобразован в <myElement>this &amp; that</myElement>.

Проблема в том, что когда я использую XmlTextWriter для сохранения файла, '&' снова экранируется в <myElement>this &amp;amp; that</myElement>. Я не хочу, чтобы этот дополнительный & в строке.

Другой пример: <myElement>• bullet</myElement>, моя обработка изменяет его на <myElement>&#8226; bullet</myElement>, который сохраняется на <myElement>&amp;#8226; bullet</myElement>. Все, что я хочу выводить в файл - это форма <myElement>&#8226; bullet</myElement>.

Я пробовал различные варианты на различных XmlWriters и т. Д., Но не могу получить необработанные строки для правильного вывода. И почему синтаксический анализатор XML не может распознавать и не переписывать уже действительные escape-коды?

обновление: после дополнительной отладки я обнаружил, что текстовые строки элементов (фактически все строки, включая теги элементов, имена, атрибуты и т. Д.) Кодируются всякий раз, когда они копируются в данные объекта .net xml ( Исключение составляют CDATA) внутренним классом с именем XmlCharType в System.Xml. Таким образом, проблема не имеет ничего общего с XmlWriters. Похоже, что лучший способ решить эту проблему - это отключить данные при выводе, либо используя что-то вроде:

string output = System.Net.WebUtility.HtmlDecode(xmlDoc.OuterXml);

Который, вероятно, превратится в пользовательский XmlWriter для сохранения форматирования и т. Д.

Спасибо всем за полезные предложения.

Ответы [ 2 ]

1 голос
/ 16 февраля 2012

Хорошо, вот решение, которое я придумала:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Versioning;
using System.Text;

namespace YourName {

    // Represents a writer that makes it possible to pre-process 
    // XML character entity escapes without them being rewritten.
    class XmlRawTextWriter : System.Xml.XmlTextWriter {
        public XmlRawTextWriter(Stream w, Encoding encoding)
            : base(w, encoding) {
        }

        public XmlRawTextWriter(String filename, Encoding encoding)
            : base(filename, encoding) {
        }

        public override void WriteString(string text) {
            base.WriteRaw(text);
        }
    }
}

и затем используем его, как если бы XmlTextWriter:

        XmlRawTextWriter rawWriter = new XmlRawTextWriter(thisFilespec, Encoding.UTF8);
        rawWriter.Formatting = Formatting.Indented;
        rawWriter.Indentation = 1;
        rawWriter.IndentChar = '\t';
        xmlDoc.Save(rawWriter);

Это работает без необходимости расшифровывать или взламыватьфункциональность кодирования.

1 голос
/ 15 февраля 2012

вместо этого вызывается xmlwriter.writeraw. Но он недостаточно умен, чтобы проверить, действительны ли символы или нет. Таким образом, вы должны проверить самостоятельно, иначе будет сгенерирован неверный xml.

...