xml изменить форматирование после удаления ненужных атрибутов.

Я использую подобный метод для чтения из каталога файлов Xml в объект XmlDocument.

private static void StripAttributes(string filePath)
    {
        Contract.Requires(filePath != null);
        var xmlDocument = new XmlDocument();
        var encode = Encoding.GetEncoding("ISO-8859-1");
        using (var sr = new StreamReader(filePath, encode))
        {
            xmlDocument.Load(sr);
        }

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

Пример из предыдущего:

<xml>
  <xml2>
     <xmlField id='foo' string='bar'><xmlValue>foobar</xmlValue></xmlField>
  </xml2>
</xml>

Пример после форматирования:

<xml>
  <xml2>
     <xmlField id="foo">
        <xmlValue>foobar</xmlValue>
     </xmlField>
  </xml2>
</xml>

Мне нужно, чтобы исходный формат оставался неизменным для целей сравнения.

Есть идеи, как сохранить исходный формат Xml?


person Jonathan Underwood    schedule 09.07.2015    source источник


Ответы (2)


Пробел

Ваша первая проблема - пробелы. В XML это обычно неважно, поэтому по умолчанию XmlDocument нормализует любые значительные пробелы, что вы и видите здесь.

Чтобы изменить это поведение, установите PreserveWhitespace = true перед загрузкой XML:

var xmlDocument = new XmlDocument
{
    PreserveWhitespace = true
};

Цитаты

Ваша вторая проблема связана с кавычками. Одинарное или двойное допустимо, но по умолчанию в .NET используется двойное. Обе модели DOM перезапишут ваш XML с использованием внутреннего XmlWriter, который использует это значение по умолчанию. Вы можете, конечно, указать свой собственный экземпляр XmlWriter.

Рекомендуется использовать XmlWriter.Create фабричные методы и указывать любые функции с помощью XmlWriterSettings, однако в данном случае это не сработает. Вам нужно будет явно создать экземпляр XmlTextWriter и изменить QuoteChar:

var writer = new XmlTextWriter(fileName, encoding)
{
    QuoteChar = '\''
};

using (writer)
{
    xmlDocument.WriteTo(writer);
}

LINQ в XML

Кроме того, я настоятельно рекомендую обратить внимание на LINQ to XML вместо старого XmlDocument API. Чтобы получить подобное поведение в XDocument, вы должны разобрать и написать так:

var doc = XDocument.Load(filePath, LoadOptions.PreserveWhitespace);
doc.WriteTo(writer);

Если, как предполагает ваш код, вы удаляете атрибуты, то такой простой код удалит все атрибуты с именем string из элементов с именем xmlField:

doc.Descendants("xmlField")
    .SelectMany(e => e.Attributes("string"))
    .Remove();
person Charles Mager    schedule 09.07.2015
comment
Спасибо, это ответ на мой вопрос. Будет ли XmlWriter работать с StreamReader или мне нужно заменить StreamReader? - person Jonathan Underwood; 09.07.2015
comment
StreamReader используется для чтения, XmlWriter используется для записи. Вы не показали, как вы пишете результирующий XML, но это то, что вам нужно будет использовать, если вы хотите, чтобы кавычки оставались одинарными. - person Charles Mager; 09.07.2015
comment
Будет xmlDocument.Save(filePath); работать или мне нужно будет изменить способ сохранения/записи Xml? - person Jonathan Underwood; 09.07.2015
comment
Нет, нужно использовать xmlDocument.WriteTo(writer) — это есть в ответе. - person Charles Mager; 09.07.2015

Возможно, вы не можете! С реализацией Microsoft.Net рендеринга xml модуль рендеринга всегда переформатирует вывод. Либо XmlDocument, либо XDocument с любой настройкой. В одном из моих проектов (Efatura в Турции) файлы xml подписаны xades и не должны изменяться. Мы поняли, что только рендеринг и сохранение без каких-либо изменений что-то меняет в xml-файле и делает подпись недействительной. Также, если, например, входной xml представляет собой только одну строку (без пробелов), синтаксические анализаторы (все) не могут проанализировать документ. Эффект, который мы наблюдали, заключается в том, что синтаксический анализатор пропускает некоторые элементы, которые ведут себя так, как будто их нет.

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

Для однострочного xml мы использовали XmlReader, но изменили механизм сопоставления.

person Mert Gülsoy    schedule 09.07.2015