使用PHP计算XML文件中某个名称的所有元素

时间:2016-11-10 14:44:13

标签: php xml

鉴于以下XML:

<Items>
    <Item>...</Item>
    <Item>...</Item>
    <Item>...</Item>
    <Item>...</Item>
</Items>

我正在编写一个函数来返回所有<Item>元素的计数(在本例中为4)。实际的XML文件很大,我不想在内存中加载整个东西以便解析它。

使用命令行,我设法通过以下行获得了我需要的东西:

grep "<Item>" my_file.xml -o | wc -l

我是否可以使用PHP中的等效解决方案来获得相同的结果?

1 个答案:

答案 0 :(得分:1)

使用XPath很容易完成:

$doc = new DOMDocument();
$doc->load('my_file.xml', LIBXML_PARSEHUGE);

$xp = new DOMXPath($doc);
$count = $xp->evaluate('count(//Item)');

XPath表达式返回文档中所有 Item标记的数量。

LIBXML_PARSEHUGE选项仅影响深度,实体递归和文本节点大小的内部限制。但是,DOM解析器将整个文档加载到内存

对于非常大的文件,使用SAX parser,它按顺序对每段XML进行操作(因此只将文档的一小部分加载到内存中):

$counter = 0;

$xml_parser = xml_parser_create();
xml_set_element_handler($xml_parser, function ($parser, $name) use (&$counter) {
  if ($name === 'ITEM') {
    $counter++;
  }
}, null);

if (!($fp = fopen('my_file.xml', 'r'))) {
  die('Could not open XML input');
}

while ($data = fread($fp, 4096)) {
  if (!xml_parse($xml_parser, $data, feof($fp))) {
    die(sprintf("XML error: %s at line %d",
      xml_error_string(xml_get_error_code($xml_parser)),
      xml_get_current_line_number($xml_parser)));
  }
}
xml_parser_free($xml_parser);