【问题标题】:Parsing XmlTextWriter object to String将 XmlTextWriter 对象解析为字符串
【发布时间】:2020-05-10 23:05:58
【问题描述】:

我正在用 C# 构建一个类库,它使用 XmlTextWriter 类构建一个 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(),这会导致同样的问题。

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

【问题讨论】:

  • 您是否尝试将输出写入"D:/HTMLWriter/XML/HTMLSaveAsConfig.xml"filepath
  • @PhilBrubaker 输出应写入文件路径。 HTMLSaveAsConfig.xml 将在对象解构时被删除。
  • 谢谢 Ben - 我也想通了。请在下面查看我的Answer,它可能会让您更接近解决这个问题的好地方。

标签: c# xml tostring xmlwriter


【解决方案1】:

以下函数将从您创建的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 对象必须同时支持“读取”和“查找”操作(即,Stream.CanReadSystem.CanSeek 属性必须分别返回 true )。

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

  1. Convert.ToString() 调用替换为对该新函数的调用。
  2. 假设您打算将filepath 参数指定的文件写入SaveAsHTML() 函数,而不是硬编码路径。
  3. System.Xml.XmlTextWriter 的创建(以及使用和处置)封装在using 块中(如果您不熟悉,请参阅What are the uses of “using” in 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 方法和 XmlWriterSettings 类创建 XmlWriter 实例,以利用新功能。

【讨论】:

  • 谢谢菲尔。通过一些调整,这应该对我有用。我最初的计划是用类似这样的方法覆盖 ToString() 方法,但鉴于该操作是在 XmlTextWriter 而不是从我的类派生的对象上进行的,我将其设为类中的受保护方法。有一些折痕要熨平,但一旦完成,我会用结果更新这个线程。
【解决方案2】:

最后一行写入 XmlTextWriter.ToString() 的值,它不会返回您编写的 XML 的文本表示形式。尝试离开最后一行,看起来您的 XmlTextWriter 已经在写入文件。

【讨论】:

    【解决方案3】:

    @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 块是我以前没有遇到过的,但它为我提供了很多全面的解决方案。所以也谢谢你!

    【讨论】:

    • 很高兴能够提供帮助!
    • 请注意,您在此处为您的StreamReader 使用的using 块会为您管理对reader.Dispose() 的调用,即使抛出异常也是如此。不过,出于语义问题,您可以在这里调用reader.Close()
    猜你喜欢
    • 2013-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-17
    • 2013-04-04
    • 2019-07-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多