XmlWriter写入字符串而不是文件


118

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

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

这将产生一个错误,指出nextXMLstring没有文件路径。它想要类似:

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

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

谢谢!!

Answers:


217

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

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

例如

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


  }
  return sw.ToString();
}

2
@Will:回滚您的更改。XmlTextWriter.Close()将刷新到流,因此希望在提取字符串之前进行该操作。(在这种情况下,差异不大,但是更喜欢一致地执行此操作,因为* Writer和Stream类的同义语义并不总是清楚地记录在案。)
Richard

1
只是对使用此功能的人的评论。如果您碰巧忽略了using(),而是正常地声明了XmlWriter,那么请确保在调用sw.ToString()之前先调用xw.Flush,否则可能无法获得所有内容!(显然最好使用使用括号...)
Ravendarksky 2014年

请记住,下面的代码提供了在代码分析CA2202警告,怎么一回事,因为Dispose()方法将两次的StringWriter对象上调用
卢卡斯Kosiak

113

正如理查德所说,这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();
}

乔恩,您确定writer不会被一次性处置吗?
rasx 2010年

2
@rasx:可能是-但没关系。
乔恩·斯基特

30

我知道这很古老并且可以回答,但是这是另一种方法。特别是如果您不想在字符串开头使用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());
}

3
Encoding.UTF8.GetString(ms.ToArray())是简化您的退货。
SliverNinja-MSFT 2012年

1
ms.ToArray()我尝试此操作时不返回任何项目。必须x.Close()在内部using语句之外添加或移动return语句。
Rich C

utf8.GetString(ms.GetBuffer(),0,(int)ms.Length); 工作?
brianary 2013年

1
@Rich C-我怀疑这是因为您的流未刷新。XmlTextWriter将被放置在其using语句之外,这将导致其刷新。
yourbuddypal 2014年

13

用途StringBuilder

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

1

伙计们不要忘记调用xmlWriter.Close()和xmlWriter.Dispose(),否则您的字符串将无法完成创建。这只是一个空字符串


不用担心,using语句将处理对象的处理。

这是2009年以来的一个问题。因此,现在提供答案的价值将是可能会遇到类似问题的未来用户。因此,只有在这样的旧问题可以清楚地识别问题并解释/提供解决方案的情况下,才应提供答案。尝试让OP参与对话通常是徒劳的,因为他们可能会继续前进。
MikeC '16

我正在浏览所有这些示例,并且想知道为什么我会得到空字符串。xmlWriter.Close()是解决方案。
拉斐尔·里斯科夫斯基

-1

好吧,我认为这里最简单,最快的解决方案是:

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());
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.