将 XmlTextWriter 对象解析为字符串

Parsing XmlTextWriter object to String

我正在用 C# 构建一个 class 库,它使用 XmlTextWriter class 构建一个 XML,然后导出为 HTML 文件。

然而,当我使用 XmlTextWriter 对象作为内容以 .html 扩展名保存文件时,生成的文件仅包含文本 "System.Xml.XmlTextWriter"

这出现在下面定义的方法中,特别是在最后一行:-

public void SaveAsHTML(string filepath)
        {
            XmlTextWriter html;
            html = new XmlTextWriter(@"D:/HTMLWriter/XML/HTMLSaveAsConfig.xml", System.Text.Encoding.UTF8);
            html.WriteStartDocument();
            html.WriteStartElement("html");
            html.WriteRaw(Convert.ToString(Head));
            html.WriteRaw(Convert.ToString(Body));
            html.WriteEndElement();
            html.WriteEndDocument();
            html.Flush();
            html.Close();
            System.IO.File.WriteAllText(filepath, html.ToString());
        }

对于上下文,变量 Head 和 Body 也是 XmlTextWriter 对象,分别包含将成为 html 文件的和元素的内容。

我试过使用 Convert.ToString(),这会导致同样的问题。

我很想尝试覆盖我的 class 的 ToString() 方法作为修复,可能会使用 XmlSerializer class。但是我想知道是否有一种噪音较小的方法将 Xml 对象作为字符串返回?

最后一行写的是XmlTextWriter.ToString()的值,不是return你写的XML的文本表示。尝试离开最后一行,看起来您的 XmlTextWriter 已经在写入文件。

以下函数将从您创建的 System.Xml.XmlTextWriter 对象中提取字符串 HeadBody.

private string XmlTextWriterToString(XmlTextWriter writer)
{
    // Ensure underlying stream is flushed.
    writer.Flush();
    // Reset position to beginning of stream.
    writer.BaseStream.Position = 0;
    using (var reader = new StreamReader(writer.BaseStream))
    {
        // Read and return content of stream as a single string
        var result = reader.ReadToEnd();
        return result;
    }
}

这里需要注意的是,与 System.Xml.XmlTextWriter 关联的基础 System.IO.Stream 对象必须同时支持 'read' 和 'seek'操作(即 Stream.CanReadSystem.CanSeek 属性必须分别 return true ).

我对您的原始代码进行了以下修改:

  1. 用对这个新函数的调用替换了 Convert.ToString() 调用。
  2. 假设您打算将 filepath 参数指定的文件写入 SaveAsHTML() 函数,而不是硬编码路径。
  3. System.Xml.XmlTextWriter 的创建(以及使用和处置)包装在 using 块中(如果您不熟悉,请参阅 “的用途是什么”在 C# 中使用”?).

以下是您进行这些更改后的代码。

public void SaveAsHTML(string filepath)
{
    using (var html = new XmlTextWriter(filepath, System.Text.Encoding.UTF8))
    {
        html.WriteStartDocument();
        html.WriteStartElement("html");
        html.WriteRaw(XmlTextWriterToString(Head));
        html.WriteRaw(XmlTextWriterToString(Body));
        html.WriteEndElement();
        html.WriteEndDocument();
        html.Flush();
        html.Close();
    }
}

另一件需要注意的事情是,无法从提供的代码中确定它们是如何被管理的,HeadBody 的生命周期受到相同的例外- 基于资源泄漏的可能性,html 在将其包装在 using 块之前。

最后的想法:System.Xml.XmlTextWriter 的页面说明如下:从 .NET Framework 2.0 开始,我们建议您使用 XmlWriter.Create 方法创建 XmlWriter 实例和 XmlWriterSettings class 以利用新功能。

@PhilBrubaker 的解决方案似乎是在正确的轨道上。我的代码中仍然存在一些错误,我正在努力修复这些错误,但好消息是转换似乎现在可以正常工作了。

protected string XmlToString(XmlWriter xmlBody)
        {
            XmlTextWriter textXmlBody = (XmlTextWriter)xmlBody;
            textxmlBody.BaseStream.Position = 0;
            using (var reader = new StreamReader(textXmlBody.BaseStream))
            {
                var result = reader.ReadToEnd();
                reader.Dispose();
                return result;
            }
        }

我已经将输入参数类型从 XmlWriter 更改为方法中的 XmlTextWriter,这样当使用 Create() 方法而不是 .NET 推荐的初始化时,该方法也能正常工作2.0。目前它不是 100% 可靠,因为 XmlWriter 并不总是正确地转换为 XmlTextWriter(取决于功能),但这超出了这个线程的范围,我正在单独调查。

感谢您的帮助!

附带说明一下,using 块是我以前从未遇到过的东西,但它为我提供了很多全面的解决方案。所以也谢谢你!