【问题标题】:XStreamingElement as part of an XDocumentXStreamingElement 作为 XDocument 的一部分
【发布时间】:2016-02-24 13:29:26
【问题描述】:

我想编写一个非常大的 XML 文档,所以System.Xml.Linq.XStreamingDocument 似乎是理想的解决方案。

我认为我可以构造 XDocument 以包含 XStreamingDocument 并且只有当我调用 Save() 时才会遍历树并迭代可枚举。

public void WriteXml(IEnumerable<string> lotsOfStrings, TextWriter output)
{
    var rootElement = new XElement("Root", 
       new XStreamingElement ("Strings", lotsOfStrings.Select(s => new XElement("Line", s))));

    var document = new XDocument(rootElement);
    document.Save(output);
}

但事实并非如此。只要我将XStreamingElement 添加到包含元素,它就会迭代可枚举并生成所有元素。

我打算将这个长元素列表嵌套在几个元素深处。在调用XStreamingElement.WriteTo() 之前,我是否必须使用XmlWriter 手动编写包含结构?这会有点乏味,最终我会混合范式(XmlWriterSystem.Xml.Linq)。这似乎真的限制了XStreamingElement 的用处。

还是我错过了构建包含流式元素的文档的某种方式?

【问题讨论】:

  • 当您将它添加到 XDocument 时,您如何知道它会遍历元素?如果您在调试时显示了它的值,那么这将导致 .ToString() 被调用并立即迭代元素。
  • @xjuice 我在Select lambda 中放置了一个断点。这在document.Save() 被击中之前就被击中了。也可以使用具有副作用的迭代器进行验证。

标签: c# .net xml linq-to-xml


【解决方案1】:

您包裹在非流式元素(即XElementXDocument)中的任何内容都会立即迭代和生成。如果您将 Root 元素类型从 XElement 更改为 XStreamingElement,则不会立即执行 linq 查询。您可以将 XElement 用于使用 linq 延迟生成的叶节点(例如您的 Line 元素),但您必须将 XStreamingElement 用于具有动态内容的任何元素想要提前生成。

您可以使用单独定义的嵌套XStreamingElement 构建更大的结构。我已经在我的代码示例中通过单独引入 Strings 元素来证明这一点。您也可以使用自己的 Iterators 而不是 linq 查询来创建动态内容。

最后但同样重要的是,XStreamingElement 有方法Save(TextWriter writer),所以你实际上也不需要XDocument

public static void WriteXml(IEnumerable<string> lotsOfStrings, TextWriter output)
{
    var stringsElement = new XStreamingElement("Strings",
        lotsOfStrings.Select(s => new XElement("Line", s)));
    var rootElement = new XStreamingElement("Root", stringsElement);

    //No XML is generated yet

    rootElement.Save(output); //Whole XML is generated and saved to output
}

【讨论】:

  • 继续。我曾认为我需要将其包装在 XDocument 中以输出 XML 指令等,但没有必要。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多