Xmlreader newline\n вместо\r\n

Когда я использую XmlReader.ReadOuterXml(), элементы разделяются \n вместо\r\n. Так, например, если у меня есть XmlDocument представительство

<A>
<B>
</B>
</A>

Я получаю

<A>\n<B>\n</B>\n</A>

Можно ли указать символ новой строки? XmlWriterSettings имеет его, но XmlReader, похоже, не имеет этого.

Вот мой код для чтения xml. Обратите внимание: XmlWriterSettings по умолчанию имеет значение NewLineHandling = Replace

XmlDocument xmlDocument = <Generate some XmlDocument>
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;

// Use a memory stream because it accepts UTF8 characters.  If we use a 
// string builder the XML will be UTF16.
using (MemoryStream memStream = new MemoryStream())
{
    using (XmlWriter xmlWriter = XmlWriter.Create(memStream, settings))
    {
        xmlDocument.Save(xmlWriter);
    }

    //Set the pointer back to the beginning of the stream to be read
    memStream.Position = 0;
    using (XmlReader reader = XmlReader.Create(memStream))
    {
        reader.Read();
        string header = reader.Value;
        reader.MoveToContent();
        return "<?xml " + header + " ?>" + Environment.NewLine + reader.ReadOuterXml();
    }
}

Ответ 1

XmlReader автоматически нормализует \r\n\ до \n. Хотя это кажется необычным для Windows, оно действительно требуется в спецификации XML (http://www.w3.org/TR/2008/REC-xml-20081126/#sec-line-ends).

Вы можете сделать String.Replace:

string s = reader.ReadOuterXml().Replace("\n", "\r\n");

Ответ 2

Мне пришлось записывать данные базы данных в xml файл и читать его обратно из XML файла, используя LINQ to XML. Некоторые поля в записи были самими xml-строками с символами \r. Они должны были остаться нетронутыми. Я провел несколько дней, пытаясь найти что-то, что сработает, но, похоже, Microsoft по дизайну конвертирует \r в\n.

Для меня работает следующее решение:

Чтобы записать загруженный XDocument в файл XML, сохраняющий \r intact, где xDoc - это XDocument, а filePath - строка:

XmlWriterSettings xmlWriterSettings = new XmlWriterSettings 
    { NewLineHandling = NewLineHandling.None, Indent = true };
using (XmlWriter xmlWriter = XmlWriter.Create(filePath, xmlWriterSettings))
{
    xDoc.Save(xmlWriter);
    xmlWriter.Flush();
}

Чтобы прочитать XML файл в XElement, сохраняя \r intact:

using (XmlTextReader xmlTextReader = new XmlTextReader(filePath) 
   { WhitespaceHandling = WhitespaceHandling.Significant })
{
     xmlTextReader.MoveToContent();
     xDatabaseElement = XElement.Load(xmlTextReader);
}

Ответ 3

Решение 1: Записать имя XML

Используйте хорошо сконфигурированный XmlWriter с NewLineHandling.Entitize, чтобы XmlReader не выполнил исключить нормализовать окончание строки.

Вы можете использовать такой пользовательский XmlWriter даже с XDocument:

xDoc.Save(XmlWriter.Create(fileName, new XmlWriterSettings { NewLineHandling = NewLineHandling.Entitize }));

Решение 2: Прочитайте необусловленный XML без нормализации

Решение 1 - более чистый способ; однако возможно, что у вас уже есть необитаемый XML, и вы не можете изменить создание и все же хотите предотвратить нормализацию. В принятом ответе предлагается заменить, но заменяет все \n вхождения вслепую, даже если это нежелательно. Чтобы получить все окончания строк, как они есть в файле, вы можете попробовать использовать устаревший класс XmlTextReader, который по умолчанию не нормализует файлы XML. Вы также можете использовать его с XDocument:

var xDoc = XDocument.Load(new XmlTextReader(fileName));

Ответ 4

Там быстрее, если вы просто пытаетесь добраться до UTF-8. Сначала создайте автора:

public class EncodedStringWriter : StringWriter
{
    public EncodedStringWriter(StringBuilder sb, Encoding encoding)
        : base(sb)
    {
        _encoding = encoding;
    }

    private Encoding _encoding;

    public override Encoding Encoding
    {
        get
        {
            return _encoding;
        }
    }

}

Затем используйте его:

XmlDocument doc = new XmlDocument();
doc.LoadXml("<foo><bar /></foo>");

StringBuilder sb = new StringBuilder();
XmlWriterSettings xws = new XmlWriterSettings();
xws.Indent = true;

using( EncodedStringWriter w = new EncodedStringWriter(sb, Encoding.UTF8) )
{
    using( XmlWriter writer = XmlWriter.Create(w, xws) )
    {
        doc.WriteTo(writer);
    }
}
string xml = sb.ToString();

Должен дать кредит, где кредит из-за.

Ответ 5

XmlReader читает файлы, а не записывает их. Если вы получаете \n в своем читателе, это происходит из-за того, что в файле. И \n и\r являются пробелами и семантически одинаковы в XML, это не повлияет на смысл или содержание данных.

Edit:

Это похоже на С#, а не на Ruby. Как сказано в binarycoder, ReadOuterXml определен для возврата нормализованного XML. Обычно это то, что вы хотите. Если вам нужен необработанный XML, вы должны использовать Encoding.UTF8.GetString(memStream.ToArray()), а не XmlReader.