【问题标题】:Best XML Parser for PHP [duplicate]PHP 的最佳 XML 解析器 [重复]
【发布时间】:2010-09-16 08:21:59
【问题描述】:

我以前使用过 XML 解析器,尽管它工作正常,但我对它总体上并不满意,感觉就像我在为应该是基本功能的事情使用变通方法。

我最近看到了 SimpleXML,但我还没有尝试过。是不是更简单了?两者都有什么优点和缺点?你用过其他的解析器吗?

【问题讨论】:

  • 对阅读本文的任何人的建议:提出一个问题,描述您需要对 XML 进行做什么(不仅仅是解析它),您可能会得到更好的答案。
  • 请参阅以下 PHP 标记的一般参考问题:How to parse and process HTML/XML with PHP?

标签: php xml parsing xml-parsing


【解决方案1】:

我不得不说SimpleXML 拿了蛋糕,因为它首先是一个扩展,用 C 编写,而且速度非常快。但其次,解析后的文档采用 PHP 对象的形式。所以你可以像$root->myElement一样“查询”。

【讨论】:

  • simplexml 是最好的。但是使用命名空间不是很好,有时会变得很棘手
  • 是的,我认为这也是最好的。我使用xpath。 $xml->xpath("//block");//这太棒了:)
  • 我认为它不是最好的。它不支持 xml version="1.1" 并对此事实发出警告(我的 PHP 版本是 5.3.6)。我知道您可以禁用警告并且它工作正常,但我认为这不是一个好的解决方案。那么想象一下,如果您的 API 提供者将 xml 文档版本从 1.0 更改为 1.1,将会发生什么?第二个想法是@Gordon 指出的。 SimpleXML 将整个文档加载到内存中。这是一个很好的解决方案,但肯定不是最好的。
  • 用 SimpleXML 处理命名空间 XML 很糟糕。
  • SimpleXML 在某个节点有一个子节点时创建不同的结构,当它有更多子节点时创建不同的结构。这让我恶心!
【解决方案2】:

这取决于您尝试对 XML 文件执行的操作。如果您只是想读取 XML 文件(如配置文件),The Wicked Flea 建议 SimpleXML 是正确的,因为它创建了相当于嵌套 ArrayObjects 的内容。例如$xml->root->child 可以访问值。

如果您希望操作 XML 文件,最好使用 DOM XML

【讨论】:

    【解决方案3】:

    看看 PHP 的available XML extensions

    XML Parser 和 SimpleXML 的主要区别在于后者不是拉式解析器。 SimpleXML 构建在 DOM 扩展之上,并将整个 XML 文件加载到内存中。像 XMLReader 这样的 XML Parser 只会将当前节点加载到内存中。您为特定节点定义处理程序,当 Parser 遇到它时将触发这些处理程序。这样更快并且节省内存。无法使用 XPath,您为此付出了代价。

    就我个人而言,我发现 SimpleXml 在它通过 DOM 提供的功能方面非常有限(因此很简单)。您可以轻松地在 DOM 和 SimpleXml 之间切换,但我通常不会打扰,直接走 DOM 路线。 DOM 是 W3C DOM API 的实现,因此您可能从其他语言(例如 JavaScript)熟悉它。

    【讨论】:

    • 那你主要用什么?
    • 抱歉 - 只是在寻找有关 API 差异的信息并来到这里。两个 devzone 链接都已失效,不确定是否应该删除或更新它们。
    【解决方案4】:

    这是一个有用的功能,可以在扩展程序不可用时快速轻松地解析 xml:

    <?php
    /**
     * Convert XML to an Array
     *
     * @param string  $XML
     * @return array
     */
    function XMLtoArray($XML)
    {
        $xml_parser = xml_parser_create();
        xml_parse_into_struct($xml_parser, $XML, $vals);
        xml_parser_free($xml_parser);
        // wyznaczamy tablice z powtarzajacymi sie tagami na tym samym poziomie
        $_tmp='';
        foreach ($vals as $xml_elem) {
            $x_tag=$xml_elem['tag'];
            $x_level=$xml_elem['level'];
            $x_type=$xml_elem['type'];
            if ($x_level!=1 && $x_type == 'close') {
                if (isset($multi_key[$x_tag][$x_level]))
                    $multi_key[$x_tag][$x_level]=1;
                else
                    $multi_key[$x_tag][$x_level]=0;
            }
            if ($x_level!=1 && $x_type == 'complete') {
                if ($_tmp==$x_tag)
                    $multi_key[$x_tag][$x_level]=1;
                $_tmp=$x_tag;
            }
        }
        // jedziemy po tablicy
        foreach ($vals as $xml_elem) {
            $x_tag=$xml_elem['tag'];
            $x_level=$xml_elem['level'];
            $x_type=$xml_elem['type'];
            if ($x_type == 'open')
                $level[$x_level] = $x_tag;
            $start_level = 1;
            $php_stmt = '$xml_array';
            if ($x_type=='close' && $x_level!=1)
                $multi_key[$x_tag][$x_level]++;
            while ($start_level < $x_level) {
                $php_stmt .= '[$level['.$start_level.']]';
                if (isset($multi_key[$level[$start_level]][$start_level]) && $multi_key[$level[$start_level]][$start_level])
                    $php_stmt .= '['.($multi_key[$level[$start_level]][$start_level]-1).']';
                $start_level++;
            }
            $add='';
            if (isset($multi_key[$x_tag][$x_level]) && $multi_key[$x_tag][$x_level] && ($x_type=='open' || $x_type=='complete')) {
                if (!isset($multi_key2[$x_tag][$x_level]))
                    $multi_key2[$x_tag][$x_level]=0;
                else
                    $multi_key2[$x_tag][$x_level]++;
                $add='['.$multi_key2[$x_tag][$x_level].']';
            }
            if (isset($xml_elem['value']) && trim($xml_elem['value'])!='' && !array_key_exists('attributes', $xml_elem)) {
                if ($x_type == 'open')
                    $php_stmt_main=$php_stmt.'[$x_type]'.$add.'[\'content\'] = $xml_elem[\'value\'];';
                else
                    $php_stmt_main=$php_stmt.'[$x_tag]'.$add.' = $xml_elem[\'value\'];';
                eval($php_stmt_main);
            }
            if (array_key_exists('attributes', $xml_elem)) {
                if (isset($xml_elem['value'])) {
                    $php_stmt_main=$php_stmt.'[$x_tag]'.$add.'[\'content\'] = $xml_elem[\'value\'];';
                    eval($php_stmt_main);
                }
                foreach ($xml_elem['attributes'] as $key=>$value) {
                    $php_stmt_att=$php_stmt.'[$x_tag]'.$add.'[$key] = $value;';
                    eval($php_stmt_att);
                }
            }
        }
        return $xml_array;
    }
    ?>
    

    【讨论】:

    • 就像一个魅力,simpleXml 在我正在处理的几个脚本中失败了,谢谢
    • 出现错误 - 注意:未定义变量:xml_array ?
    • 谢谢,这解决了我的 simpleXml 问题!
    【解决方案5】:

    crxml 解析器是一个真正易于解析的解析器。

    这个类有一个搜索功能,它接受一个带有任何命名空间的节点名称作为参数。它在 xml 中搜索节点并打印出访问语句以使用此类访问该节点。这个类也使得 xml 的生成变得非常容易。

    你可以下载这个课程

    http://freshmeat.net/projects/crxml

    或来自 phpclasses.org

    http://www.phpclasses.org/package/6769-PHP-Manipulate-XML-documents-as-array.html

    【讨论】:

    • 您可能想透露您是该课程的作者。
    • PHPClasses.org 还是个东西?编辑:哦,我猜它还是在 11 年
    【解决方案6】:

    您好,我认为 SimpleXml 非常有用。 有了它,我正在使用xpath;

    $xml = simplexml_load_file("som_xml.xml");
    
    $blocks  = $xml->xpath('//block'); //gets all <block/> tags
    $blocks2 = $xml->xpath('//layout/block'); //gets all <block/> which parent are   <layout/>  tags
    

    我使用了许多 xml 配置,这有助于我非常快速地解析它们。 SimpleXml 写在 C 上,所以速度非常快。

    【讨论】:

      猜你喜欢
      • 2013-03-24
      • 1970-01-01
      • 2019-01-06
      • 2010-12-04
      • 2019-05-15
      • 2010-09-27
      • 1970-01-01
      • 2011-09-05
      相关资源
      最近更新 更多