在PHP中不能使用DOMNamedNodeMap类型的对象作为数组错误?

时间:2015-08-17 10:28:43

标签: php xml

我使用以下代码来解析XML:

foreach ($rss->getElementsByTagName('item') as $node) {
    $item = array(
    'title' => $node->getElementsByTagName('title')->item(0)->nodeValue,
    'desc' => $node->getElementsByTagName('enclosure')->item(0)->attributes['url']->nodeValue,
    'link' => $node->getElementsByTagName('link')->item(0)->nodeValue
    );
    array_push($feed, $item);
}

它在localhost上完美运行,没有任何错误。但是,在服务器上,存储Cannot use object of type DOMNamedNodeMap as array的中间行会出现desc错误。是什么导致了这个问题?

2 个答案:

答案 0 :(得分:2)

问题在于:

$node->getElementsByTagName('enclosure')->item(0)->attributes['url']->nodeValue

您正在使用以下内容获取元素节点:

$node->getElementsByTagName('enclosure')->item(0)...

元素节点具有属性属性,即DOMNamedNodeList的实例。这不是一个数组,也没有实现ArrayAccess。因此,您无法使用数组语法访问属性节点。您必须使用方法DOMNamedNodeList::getNamedItem()

$node
  ->getElementsByTagName('enclosure')
  ->item(0)
  ->attributes
  ->getNamedItem('url')...

这将返回属性节点,因此您可以使用DOMAttribute::$value访问其值。

$node
  ->getElementsByTagName('enclosure')
  ->item(0)
  ->attributes
  ->getNamedItem('url')
  ->value

但是,您可以使用DOMElement::getAttribute()直接从元素节点获取属性值。

$node
  ->getElementsByTagName('enclosure')
  ->item(0)
  ->getAttribute('url')

更好的方法是使用XPath。 DOMXpath::evaluate()允许您使用表达式从DOM中获取节点和标量值。

$rss = new DOMDocument();
$rss->loadXml($rssFeedXml);
$xpath = new DOMXpath($rss);

foreach ($xpath->evaluate('//item') as $itemNode) {
  $feed[] = [
    'title' => $xpath->evaluate('string(title)', $itemNode),
    'desc' => $xpath->evaluate('string(enclosure/@url)', $itemNode),
    'link' => $xpath->evaluate('string(link)', $itemNode)
  ];
}

答案 1 :(得分:-1)

您可以尝试将节点列表显式地转换为数组,以查看是否可以解决问题 - 完全未经测试的顺便说一下。

<?php
    $items=$rss->getElementsByTagName('item');
    if( is_object( $items ) ){

        $col=(array)$items;
        if( !is_array( $col ) ) exit('Not an array!');

        foreach ( $col as $node ) {
            $item = array(
                'title' => $node->getElementsByTagName('title')->item(0)->nodeValue,
                'desc'  => $node->getElementsByTagName('enclosure')->item(0)->attributes['url']->nodeValue,
                'link'  => $node->getElementsByTagName('link')->item(0)->nodeValue
            );

            array_push( $feed, $item );
        }
    } else {
        exit( 'Type: '.gettype( $items ) );
    }
?>