【问题标题】:Copy single element of XML document being created by XMLWriter复制由 XMLWriter 创建的 XML 文档的单个元素
【发布时间】:2018-02-28 14:14:26
【问题描述】:

我的 C# 应用程序具有将对象列表 (inputList) 作为参数的方法,它使用 TextWriter 和 XMLWriter 创建一个 XML 字符串,并使用下面的代码提交到 Web 服务。

using (TextWriter writer = new Utf8StringWriter())
{
    using (XmlWriter xw = XmlWriter.Create(writer, settings))
    {
        xw.WriteStartElement("submission");
        xw.WriteElementString("version", XMLversion);
        xw.WriteElementString("user", USER_NAME);

        foreach (var obj in inputList)
        {
            xw.WriteStartElement("node");
            xw.WriteElementString("data1", obj.data1.ToString());
            xw.WriteElementString("data2", obj.data2.ToString());
            xw.WriteElementString("data3", obj.data3.ToString());
            xw.WriteElementString("data4", obj.data4.ToString()); 
            xw.WriteEndElement();
        }

    }
    xmlFile = writer.ToString();
}

记录列表中每个项目的提交的要求之一。所以我想知道是否有更有效的方法在foreach 循环中创建 XML 节点的字符串?

之后我考虑过将 XMLReader 与字符串一起使用,但这是一个全新的过程,虽然我知道我可以手动创建它,并且很高兴这样做,但我愿意接受其他建议。本质上,我正在寻找一种有效的技术来生成如下所示的字符串:

<node>
    <data1>obj.data1.ToString()</data1>
    <data2>obj.data2.ToString()</data2>
    <data3>obj.data3.ToString()</data3>
    <data4>obj.data4.ToString()</data4>
</node>

【问题讨论】:

  • 你试过简单地序列化对象吗?
  • 我推荐使用 Linq-to-XML 来生成 XML 文档。 MSDN 链接是:docs.microsoft.com/en-us/dotnet/csharp/programming-guide/…
  • 不要试图使用 StringBuilder 以谷仓方式生成字符串,XmlWriter 会处理许多重要的事情,例如字节编码和将输入字符(如 '>' 转换为 '>'以便生成的流格式正确。
  • 我喜欢序列化它的想法@DiskJunky,会尝试的。毕竟,数据在日志中存储为 blob,所以谁在乎呢?
  • 谢谢@diberium 我不明白这将如何解决我的问题。

标签: c# xmlwriter textwriter


【解决方案1】:

您的 XML 文档似乎不足以保证使用 XmlWriter 和 XmlReader。假设它可以舒适地放入内存中,那么我会使用 XmlDocument,它允许您将节点的 OuterXml(或 InnerXml,如果您愿意)作为字符串获取。

var document = new XmlDocument();

var submission = document.CreateElement("submission");
document.AppendChild(submission);

var version = document.CreateElement("version");
submission.AppendChild(version);
var versionText = document.CreateTextNode(XMLversion);
version.AppendChild(versionText);

var user = document.CreateElement("user");
submission.AppendChild(user);
var userText = document.CreateTextNode(USER_NAME);
user.AppendChild(userText);

foreach (var obj in inputList)
{
    var node = document.CreateElement("node");
    submission.AppendChild(node);

    var data1 = document.CreateElement("data1");
    node.AppendChild(data1);
    var data1Text = document.CreateTextNode(obj.data1.ToString());
    data1.AppendChild(data1Text);

    // TODO: repeat last 4 lines for data2, data3 and data4

    Console.WriteLine(node.OuterXml);
}

Console.WriteLine(document.OuterXml);

【讨论】:

  • 这看起来很有希望 Jono,但在某些情况下,inputlist 可能包含 1,000 多个项目,XMLDocument 类会管理吗?
  • 一种尺寸几乎不可能适合所有人。您将需要在 CPU 和内存使用之间找到最适合您自己需求的权衡点。上述技术使用 XmlDocument 作为内存缓存;它将处理数千个元素,但代价是在您使用它时将整个文档保存在内存中。另一方面,XmlWriter 可以直接写入流(它不必是 FileStream 或 MemoryStream)。通过精心设计的代码重用,您可以将对象列表写入两个不同的流。哪种方法最好取决于您的环境限制。
  • 我已经对各种方法进行了一些研究,虽然您的方法和上面使用 LINQ 的建议方法可能是更简单的方法,但似乎 XmlWriter 对我的用例来说是最有效的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-03-21
  • 1970-01-01
  • 2012-11-22
  • 2019-12-20
  • 1970-01-01
  • 1970-01-01
  • 2021-06-18
相关资源
最近更新 更多