我有一个100 + MB的XML文件(sans-DTD / Schema)。 XSLT将没有它。转换/解析策略?

时间:2020-03-06 14:52:59  来源:igfitidea点击:

该XML文件包含去年全年的已归档新闻报道。我被要求按故事类别将这些故事分类到新的XML文件中。

big_story_export.xml

变成

lifestyles.xml
food.xml
nascar.xml

...等等。

我使用一次性Python脚本完成了工作,但是,我最初尝试使用XSLT进行此操作。当我选择的XPATH束缚着床时,这导致了挫败感。测试文件进行了完美的转换,但是将大文件放在我的样式表中什么都没有。

我们建议采取什么策略来确保将此类文件通过XSLT运行?这是由供应商交给我的,所以可以想象一下,在定义此文件的结构时我没有太多的影响力。

如果你们想要代码示例,我将它们放在一起。

如果有的话,我将对使XML + XSLT顺利协作的一些技巧感到满意。

@sklivvz

我正在使用python的libxml2和libxslt处理此问题。我现在正在调查xsltproc。

对于这些一次性情况,它似乎是一个很好的工具。谢谢!

@ diomidis-spinellis

它的格式正确,但是(如前所述)我没有能力去发现它的有效性。

至于编写模式,我喜欢这个主意。

如果这是一次性的事情,那么我花大量的时间来验证这个文件是不切实际的,尽管我预言必须从我们的供应商处处理更多这样的文件。

编写模式(并将其提交给供应商)将是管理此类XML funk的极好的长期策略。谢谢!

解决方案

我们使用的是哪种语言/解析器?
对于大文件,我尝试使用Unix命令行工具。
它们通常比其他解决方案高效得多,并且不会"淘汰"大型文件。

尝试使用xsltproc

这听起来像是大型XML文件或者XSLT处理器中的错误。我们应该检查文件中的两件事。

  • 文件格式正确吗?也就是说,所有标签和属性是否都正确终止和匹配? XML处理器(例如xmlstarlet)可以告诉我们。
  • 该文件是否包含有效的XML?为此,我们需要一个模式和一个XML验证器(xmlstarlet也可以做到这一点)。我建议我们投入一些精力来编写文件的架构定义。这将大大简化调试过程,因为我们可以轻松地找到可能存在的问题的确切来源。

如果文件格式正确且有效,但是XSLT处理器仍拒绝为我们提供预期的结果,则可以确定问题出在处理器上,我们应该尝试使用其他处理器。

我能推荐一下Saxon XSLT处理器吗,只要我们为Java JVM提供足够的内存,它就可以处理大文件。

另一件事是,XSLT可能有一些优化可能会有所帮助,但是很难对此类事情做出明确的表述。

使用XSLT处理任意大的XML文档的问题在于,XSLT处理始于将输入文档解析为源树。这棵树被解析到内存中。这意味着,即使我们使用的是像Saxon这样的功能强大的XSLT处理器,并且拥有足够的虚拟内存,最终我们也会遇到足够大的输入文档,从而引起问题。 (它可能仍然有效,但是会很慢。)

不使用XSLT的另一个原因是,我们正在生成多个输出文档,这(基于我们到目前为止所说的)意味着我们正在对输入文档进行多次传递。

采取基于SAX的方法而不是使用XSLT可能更好(具体取决于我们所处情况的许多因素)。使用SAX处理器,我们可以编写一种方法,该方法对源文档进行一次仅向前的传递,对其进行解析,并在遇到包含它们的元素时写入所有输出文档。

查看Apache的Xalan C ++。以我的经验,在其他人(包括Saxon)无法处理"大" XML文件(> 600 MB)的情况下,它可以运行以节省内存。