问题 xmlreader换行符\ n而不是\ r \ n


当我使用XmlReader.ReadOuterXml()时,元素由\ n而不是\ r \ n分隔。 所以,例如,如果我有XmlDocument representatino

<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();
    }
}

11596
2017-11-25 00:22


起源

当输入xml具有\ r \ n和\ n的混合时,并且当下游系统对两者之间的差异敏感时,例如,这是更麻烦的。 Xml文档是一个中间状态,用于在将输出编码为具有特定分隔符的平面文件之前执行xslt转换。 - David Burg


答案:


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");

11
2017-11-25 00:42





我必须使用LINQ to XML将数据库数据写入xml文件并从xml文件中读回。记录中的某些字段本身是xml字符串,其中包含\ r \ n字符。这些必须保持完整。我花了好几天试图找到一些可行的东西,但似乎微软通过设计将\ r转换为\ n。

以下解决方案适合我:

要将加载的XDocument写入XML文件,保持\ r完整,其中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完整:

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

4
2017-08-16 16:37



谢谢你,非常感谢我的帮助! - m.t.bennett
谢谢,工作就像一个魅力! - huseyint
这是因为XmlTextReader的规范化设置默认为false,与XmlReader.Create不同,XmlReader.Create总是规范化换行符,无论如何。看到 msdn.microsoft.com/en-us/library/... 和结尾的笔记 msdn.microsoft.com/en-us/library/... - David Burg


解决方案1:编写授权XML

使用配置良好 XmlWriter 同 NewLineHandling.Entitize 选项所以 XmlReader 将不会 消除 规范化行尾。

你可以使用这样的自定义 XmlWriter 即使 XDocument

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

解决方案2:在不进行规范化的情况下读取未授权的XML

解决方案1是更清洁的方式;但是,您可能已经拥有未授权的XML,并且无法修改创建,但仍希望阻止规范化。接受的答案暗示了替换,但即使不可取,也会盲目地替换每一次。要检索文件中的所有行结尾,您可以尝试使用旧版 XmlTextReader class,默认情况下不规范化XML文件。你可以用它 XDocument,也是:

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

2
2018-01-24 14:39





如果您只是想尝试使用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();

必须在信用的地方给予信任 应有


0
2017-11-25 02:37





XmlReader读取文件,而不是写入文件。如果你正在读取你的读者,那是因为这就是文件中的内容。 \ n和\ r都是空格,在XML中语义相同,它不会影响数据的含义或内容。

编辑:

这看起来像C#,而不是Ruby。正如二进制编码器所说,ReadOuterXml被定义为返回规范化的XML。通常这就是你想要的。如果你想要原始XML,你应该使用 Encoding.UTF8.GetString(memStream.ToArray())不是 XmlReader


-1
2017-11-25 00:32



Dour,我添加了我的代码。如果我使用XmlWriter和NewLineHandling = Replace,它不应该写正确的字符串吗? - user156144