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 写入字符串而不是文件的主要内容,如果未能解决你的问题,请参考以下文章
如何将 EntityReference(例如 )写入 XmlNodeReader 读取的 XmlWriter?