显示数据节点的最快方式&x2B;它的所有属性都是PHP吗?

显示数据节点的最快方式&x2B;它的所有属性都是PHP吗?,php,optimization,dom,Php,Optimization,Dom,我正在使用php获取xml文件,并将它们转换为带有设置列的单行制表符分隔的纯文本(即,如果数据库不需要,则忽略某些标记,某些标记将为空)。我遇到的问题是,浏览56k(+更改)文件花了13分钟,我认为速度太慢了。(平均文件夹有超过一百万个xml文件)无论如何,我可能会在一夜之间完成它,但当我在处理诸如丢失文件和损坏文件之类的事情时,它以合理的速度是完全不稳定的 这里希望有人能帮助我加快速度,因为xml文件本身并不太大(注释可能有点短,因此我将其作为一个答案: 很难说您的设置在哪里可以从优化中受益。

我正在使用php获取xml文件,并将它们转换为带有设置列的单行制表符分隔的纯文本(即,如果数据库不需要,则忽略某些标记,某些标记将为空)。我遇到的问题是,浏览56k(+更改)文件花了13分钟,我认为速度太慢了。(平均文件夹有超过一百万个xml文件)无论如何,我可能会在一夜之间完成它,但当我在处理诸如丢失文件和损坏文件之类的事情时,它以合理的速度是完全不稳定的


这里希望有人能帮助我加快速度,因为xml文件本身并不太大(注释可能有点短,因此我将其作为一个答案:

很难说您的设置在哪里可以从优化中受益。也许可以在加载之前将多个XML文件连接在一起

从您在问题中提供的信息来看,我认为需要花费时间的更多是磁盘操作,而不是XML解析。我发现DomDocument和Xpath即使在大文件上也相当快。一个高达60 MB的XML文件加载大约需要4-6秒,一个2MB的文件只需要一小部分时间

拥有许多小文件(<1k)意味着需要在磁盘上进行大量工作,打开/关闭文件。此外,我不知道如何迭代目录/文件,有时这也会大大加快速度。特别是当你说你有数百万个文件节点时

因此,连接/合并文件可能是您的一个选择,它可以非常安全地运行,以减少测试转换器的时间

如果遇到丢失或损坏的文件,您应该创建日志并捕获这些错误。这样您就可以让作业运行并在以后检查错误

此外,如果可能,您可以尝试使工作流可恢复。例如,如果发生错误,将保存当前状态,下次您可以继续此状态

在注释中,在文件上运行XSLT也是一个好主意,首先要对它们进行转换。中间有一个新的层来转置数据有助于减少整体问题,因为它可以降低复杂性。

到目前为止,此XML文件工作流对我有所帮助:

  • 预处理文件(纯文本过滤器,可选)
  • 解析XML。这将加载到DomDocument、XPath迭代等
  • 我的解析器在找到解析数据时发送事件
  • 如果遇到非预期格式的数据,解析器将抛出特定异常。这允许在自己的解析器中实现错误
  • 每隔一个错误也会转换为异常
  • 可以捕获异常并完成操作。例如,转到下一个文件等
  • 记录器、简历器和导出器(文件导出)可以挂接到事件上
  • 我构建了这样一个系统来处理较大的XML文件,这些文件的格式会发生变化。它足够灵活,可以处理变化(例如,在保持日志记录和导出的同时用新版本替换解析器)。事件系统真的为我推动了它


    在迭代domnodelist时,我通常使用
    $state
    变量作为解析器状态,而不是一个巨大的switch语句。
    $state
    可以方便地在以后恢复操作。恢复状态并转到最后一个已知位置,然后继续。

    我会认真研究XSLT,以便将转换为另一种格式。Resumable和错误日志文件绝对是一个好主意,我可能现在就实现=)。我的意思是错误/缺少文件,因为一旦脚本认为它完成了,仍然有一些文件没有查看,不幸的是,这些文件已经好几个小时没有出现了。我用
    遍历目录中的文件,而(false!=($file=readdir($dirh))
    则您可能应该重命名当前正在处理的文件,并在处理后重命名它。然后,您可以在文件名中看到哪些文件已处理,哪些未处理。
    function dataNode ($entries) {
        $out = "";
    
        foreach ($entries as $e) {
            $out .= $e->nodeValue."[ATTRIBS]";
            foreach ($e->attributes as $name => $node)
                $out .= $name."=".$node->nodeValue;
        }
    
        return $out;
    }