【问题标题】:How do I copy portions of an xml file如何复制 xml 文件的部分内容
【发布时间】:2014-03-11 01:32:30
【问题描述】:

我有一个比较大的 xml 文件。即使我只需要文件的一部分,客户也会向我发送一个完整的文件。因此,我想解析出我需要的部分并处理这个新文件。

这是xml的一部分

<Activity>
    <RetailFormat>ABC</RetailFormat>
    <FeedDate>2014-02-06 21:01:10</FeedDate>
    <ActivityId>665507</ActivityId>
    <ActivityTitle>ABC 3.9.14 Hawaii </ActivityTitle>
    <StartDate>2014-03-09</StartDate>
    <EndDate>2014-03-15</EndDate>
    <StartTime>00:00:00</StartTime>
    <EndTime>23:59:59</EndTime>
    <JANumber>0</JANumber>
    <PlanItemNo>0</PlanItemNo>
    <ChannelType>Circular</ChannelType>
    <Version>
    </Version>
</Activity>

我有一个需要搜索的 ActivityID 列表。如果 ActivityID 在列表中,我想将整个 Activity 复制到一个新文件中。如果没有,我想转到下一个活动。实际上是从开始标签向下的几百行。除了手动解析部分之外,我没有使用过 xml。我不知道是否有程序化的方式来处理这个问题。另外,我可能需要这个文件中的 15K 行。该文件中有 1.3MM 行。通过限制处理文件的大小,我可以大大缩短处理时间。

我正在寻找解决此问题的最有效方法。我暂时可以手动执行此操作,但我宁愿尽早限制它。

【问题讨论】:

  • 这里有一个很大的“如果”……但“如果”文件已格式化,即。每行一行而不是一个巨大的无格式文本/xml文件,然后您可以将其视为普通文件并使用流阅读器,直到找到与您要查找的内容匹配的行,这将节省内存并成为非常快。选项二,linq-to-xml 并遵循此示例:msdn.microsoft.com/en-us/library/vstudio/…

标签: xml xml-parsing linq-to-xml


【解决方案1】:

如果文件非常大并且内存使用是一个问题,您应该使用 SAX 解析器(以您选择的语言 - 将其添加到您的标签中)。 SAX 不适用于树,因此您必须在解析时自己重建子树。优点是它不必将整个 XML 加载到内存中。你只存储你真正需要的东西。

SAX 解析器是一个基于事件的 XML 解析器,它将按顺序读取您的文件并产生事件。事件在startElement(...)startDocument(...)endElement(...)characters(...) 等方法中处理。您必须编写一个处理程序来捕获您希望处理实现这些方法的事件。

您的处理程序必须实现startElement()characters()endElement(),并使用实例变量来保存您在方法之间需要的相关数据(例如:当前元素、用于存储代码片段的数组等.

如果内存不是问题,您可以使用 DOM 或 XSLT。使用 DOM,您可以使用 getElementsByTagName("Activity") 检索 &lt;Activity&gt; 子树的数组,然后使用该子树上的 DOM 方法检查 &lt;ActivityID&gt;。然后你可以复制你想要的子树,将它们添加到另一个根,或者从当前根中删除你不想要的。

使用 XSLT,您可以编写一个 XML 模板,该模板使用 XPath 表达式(例如 //Activity)选择所有 &lt;Activity&gt; 节点,检查 ID,将 //Activity/ActivityID 与您的 ID 列表进行比较,并生成仅包含 @987654337 的结果树@你想要的节点。

告知您使用的语言,我也许可以给您发送一些示例。

【讨论】:

  • 我与编程语言无关。我基本上会像和其他一些人一样学习这门语言。我最大的问题是,当我过去进行手动解析时,我已将 70 meg 文件减少到 5 个以下。是否有适合此类操作的语言?
  • 我上面描述的解决方案是使用 Java 或 Ruby 中的 SAX 解析器解决问题的方法。 Objective-C 中的 NSXMLParser 也做了类似的事情。我不知道在 C# 或 LINQ 中有这样的事情,但我并不是一个真正的 .NET 程序员,而且我很长时间没有使用 C#,所以我可能错了。您可能能够使用 XmlReader 以节省内存的方式在 C# 中读取 XML 流。 XLinq 使用像 DOM 这样的对象模型,并且必须在处理之前将完整的 XML 加载到内存中(据我所知,在 Linq to XML 中仍然如此)。
  • 我在 Java 中有一个示例,它使用两个类(一个用于启动解析器,另一个用于处理标签事件)基于 XML 源文件中的子节点提取数据,该文件具有相同的结构你的。我现在上传到 github 并尽快发布链接。
  • 感谢您的帮助 Holderdarocha
  • This is a simple example in Java。这是类似于您的source XML。这是电影列表。 This class 是处理标签事件的地方。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-28
  • 1970-01-01
  • 1970-01-01
  • 2013-03-11
  • 1970-01-01
相关资源
最近更新 更多