13

当我使用 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();
    }
}
4

5 回答 5

15

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");
于 2009-11-25T00:42:18.407 回答
4

我必须使用 LINQ to XML 将数据库数据写入 xml 文件并从 xml 文件中读取。记录中的某些字段本身就是带有 \r 字符的 xml 字符串。这些必须保持完整。我花了几天时间试图找到可行的方法,但微软似乎有意将 \r 转换为 \n。

以下解决方案对我有用:

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

using (XmlTextReader xmlTextReader = new XmlTextReader(filePath) 
   { WhitespaceHandling = WhitespaceHandling.Significant })
{
     xmlTextReader.MoveToContent();
     xDatabaseElement = XElement.Load(xmlTextReader);
}
于 2011-08-16T16:37:02.780 回答
3

解决方案 1:编写实体化 XML

使用配置良好XmlWriterNewLineHandling.Entitize选项,这样XmlReader就不会消除规范化行尾。

XmlWriter您甚至可以使用这样的自定义XDocument

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

解决方案 2:在没有规范化的情况下读取非实体化 XML

解决方案 1 是更清洁的方法;但是,您可能已经拥有未授权的 XML,并且您无法修改创建,但您仍想阻止规范化。接受的答案建议进行替换,但即使不需要,也会盲目地替换每一次出现的 \n 。要检索文件中的所有行尾,您可以尝试使用 legacyXmlTextReader类,默认情况下不会规范化 XML 文件。您也可以将其与 一起使用XDocument

var xDoc = XDocument.Load(new XmlTextReader(fileName));
于 2017-01-24T14:39:33.367 回答
0

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

必须在信用到期的地方给予信用。

于 2009-11-25T02:37:56.330 回答
-2

XmlReader 读取文件,而不是写入文件。如果您在阅读器中收到 \n ,那是因为文件中包含这些内容。\n 和 \r 都是空格,在 XML 中语义相同,不会影响数据的含义或内容。

编辑:

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

于 2009-11-25T00:32:47.723 回答