如何在XML中获取所有<additional_image_link>节点并转为数组?
解决PHP从XML中提取所有additional_image_link节点到数组的问题
问题场景
需要从Google Shopping格式的XML中,提取每个<item>下的所有<g:additional_image_link>节点内容并存入数组。现有代码能正确统计每个item下的节点数量,但只能获取第一个节点的内容,无法拿到全部链接。
原代码及问题
原代码片段:
$reader = XMLReader::open($path); $document = new DOMDocument(); $xpath = new DOMXpath($document); while ( $reader->read() && $reader->localName !== 'item' ) { continue; } while ($reader->localName === 'item') { // expand into DOM $item = $reader->expand($document); $query = 'count(g:additional_image_link)'; $entries = $xpath->evaluate($query, $item); echo "There are $entries additional_image_links\n"; $nodes = $xpath->evaluate('string(g:additional_image_link)', $item); echo "\n<pre>nodes"; var_dump($nodes); echo '</pre>';
问题出在string(g:additional_image_link)——XPath的string()函数仅会返回匹配到的第一个节点的文本值,所以只能拿到第一个图片链接。
对应的XML结构
<?xml version="1.0" encoding="UTF-8" ?> <rss version="2.0" xmlns:g="http://base.google.com/ns/1.0" xmlns:atom="http://www.w3.org/2005/Atom"> <channel> <item> <title>A</title> <g:additional_image_link>https://image1.jpg</g:additional_image_link> <g:additional_image_link>https://image2.jpg</g:additional_image_link> </item> <item> <title>B</title> <g:additional_image_link>https://image3.jpg</g:additional_image_link> <g:additional_image_link>https://image4.jpg</g:additional_image_link> <g:additional_image_link>https://image4.jpg</g:additional_image_link> </item> </channel> </rss>
解决方案
修改XPath查询逻辑,直接获取所有<g:additional_image_link>节点的集合,再遍历提取每个节点的文本值存入数组:
$reader = XMLReader::open($path); $document = new DOMDocument(); $xpath = new DOMXpath($document); // 定位到第一个item节点 while ($reader->read() && $reader->localName !== 'item') { continue; } // 遍历所有item节点 while ($reader->localName === 'item') { // 将当前item节点转为DOM节点 $item = $reader->expand($document); // 统计节点数量(保留原逻辑) $count = $xpath->evaluate('count(g:additional_image_link)', $item); echo "当前item下有 $count 个图片链接\n"; // 获取所有g:additional_image_link节点集合 $imageNodes = $xpath->evaluate('g:additional_image_link', $item); // 初始化数组存储链接 $imageLinks = []; foreach ($imageNodes as $node) { // 提取每个节点的文本值存入数组 $imageLinks[] = $node->nodeValue; } // 输出结果验证 echo "图片链接数组:\n"; var_dump($imageLinks); // 移动到下一个item节点,避免死循环 $reader->next('item'); }
关键说明
- 去掉XPath中的
string(),直接查询g:additional_image_link会返回所有匹配的节点组成的DOMNodeList - 遍历
DOMNodeList,通过$node->nodeValue提取每个节点的文本内容 - 必须调用
$reader->next('item')移动到下一个item节点,防止进入死循环
内容的提问来源于stack exchange,提问作者Gunnarius
相关产品推荐
相关产品推荐

