XmlWriter 写入字符串而不是文件

Posted

技术标签:

【中文标题】XmlWriter 写入字符串而不是文件【英文标题】:XmlWriter to Write to a String Instead of to a File 【发布时间】:2010-10-31 15:13:44 【问题描述】:

我有一个需要返回 XML 字符串的 WCF 服务。但似乎作者只想建立一个文件,而不是一个字符串。我试过了:

string nextXMLstring = "";
using (XmlWriter writer = XmlWriter.Create(nextXMLstring))

这会生成一个错误,提示 nextXMLstring 没有文件路径。它想要这样的东西:

using (XmlWriter writer = XmlWriter.Create("nextXMLstring.xml"))

如何构建我的 XML,然后将其作为字符串返回??

谢谢!!

【问题讨论】:

【参考方案1】:

您需要创建一个 StringWriter,并将其传递给 XmlWriter。

XmlWriter.Create 的字符串重载用于文件名。

例如

using (var sw = new StringWriter()) 
  using (var xw = XmlWriter.Create(sw)) 
    // Build Xml with xw.


  
  return sw.ToString();

【讨论】:

@Will:回滚您的更改。 XmlTextWriter.Close() 将刷新到流中,因此希望在提取字符串之前发生这种情况。 (在这种情况下差别不大,但更愿意始终如一地这样做,因为 *Writer 和 Stream 类的刷新语义并不总是清楚地记录在案。) 只是对使用它的人的评论。如果您碰巧省略了 using() 而是正常声明您的 XmlWriter ,请确保在调用 sw.ToString() 之前调用 xw.Flush ,否则您可能无法获得所有内容! (显然使用方括号更好......) 请记住,以下代码在代码分析过程中会发出 CA2202 警告,因为 Dispose() 方法将在 StringWriter 对象上被调用两次 这是我正在寻找的答案,谢谢!【参考方案2】:

正如理查德所说,StringWriter 是前进的方向。然而,有一个障碍:默认情况下,StringWriter 会将自己宣传为 UTF-16 格式。 通常 XML 是 UTF-8。您可以通过子类化 StringWriter 来解决此问题;

public class Utf8StringWriter : StringWriter

    public override Encoding Encoding
    
         get  return Encoding.UTF8; 
    

这将影响XmlWriter 编写的声明。当然,如果您随后以二进制形式将字符串写入其他地方,请确保您使用的编码与您为StringWriter 修复的任何编码相匹配。 (上面的代码总是假定 UTF-8;在构造函数中制作一个接受编码的更通用的版本是微不足道的。)

然后你会使用:

using (TextWriter writer = new Utf8StringWriter())

    using (XmlWriter xmlWriter = XmlWriter.Create(writer))
    
        ...
    
    return writer.ToString();

【讨论】:

Jon,你确定writer 没有被多次处理吗? @rasx:可能是——但没关系。【参考方案3】:

我知道这是旧的并且已回答,但这是另一种方法。特别是如果您不想在字符串开头使用 UTF8 BOM,并且希望文本缩进:

using (var ms = new MemoryStream())
using (var x = new XmlTextWriter(ms, new UTF8Encoding(false)) 
                    Formatting = Formatting.Indented )

     // ...
     return Encoding.UTF8.GetString(ms.ToArray());

【讨论】:

Encoding.UTF8.GetString(ms.ToArray()) 是您退货的简化版。 ms.ToArray() 在我尝试此操作时不返回任何项目。必须添加 x.Close() 或将 return 语句移到内部 using 语句之外。 是否 utf8.GetString(ms.GetBuffer(), 0, (int)ms.Length);工作吗? @Rich C - 我怀疑这是因为您的流未刷新。 XmlTextWriter 将被置于其 using 语句之外,这将导致它刷新。【参考方案4】:

使用StringBuilder:

var sb = new StringBuilder();
    using (XmlWriter xmlWriter = XmlWriter.Create(sb))
    
        ...
    
return sb.ToString();

【讨论】:

【参考方案5】:

大家不要忘记调用 xmlWriter.Close() 和 xmlWriter.Dispose() ,否则你的字符串将无法完成创建。它只是一个空字符串

【讨论】:

别担心,using语句会处理对象的处置。 这是一个 2009 年的问题。因此,现在提供答案的价值对于未来可能遇到类似问题的用户而言。因此,只有当他们能够清楚地识别问题并解释/提供解决方案时,才应提供此类旧问题的答案。尝试让 OP 参与对话通常是徒劳的,因为他们可能已经继续前进了。 我浏览了所有这些示例,想知道为什么我会得到空字符串。 xmlWriter.Close() 是解决方案。【参考方案6】:

嗯,我认为这里最简单和最快的解决方案就是:

StringBuilder sb = new StringBuilder();

using (var writer = XmlWriter.Create(sb, settings))

    ... // Whatever code you have/need :)

    sb = sb.Replace("encoding=\"utf-16\"", "encoding=\"utf-8\""); //Or whatever uft you want/use.
    //Before you finally save it:
    File.WriteAllText("path\\dataName.xml", sb.ToString());

【讨论】:

以上是关于XmlWriter 写入字符串而不是文件的主要内容,如果未能解决你的问题,请参考以下文章

xmlreader与xmlwriter里的几个坑与解决方案

如何将 EntityReference(例如 )写入 XmlNodeReader 读取的 XmlWriter?

通过XmlWriter写入XML

PHP XMLReader 读取、编辑节点、编写 XMLWriter

使用 C# 使用特殊字符写入 XML 文档

PHP和XmlWriter更改缩进字符串