如何在PHP中扩展DOMNodeList

时间:2017-02-25 09:12:22

标签: php dom

我正在研究DOMXPath库的扩展。 我想从像这样的节点列表中提取信息

$aHref = (new DOMXPath($domDoc))->query('descendant-or-self::base')
                                ->extract(array('href'));

我的提取方法就像这样

public function extract($attributes)
{
    $attributes = (array) $attributes;
    $data = array();

    foreach ("Allnodes" as $node) {  // How can I get all nodes from the query?
        $elements = array();
        foreach ($attributes as $attribute) {
                $data[] = $node->getAttribute($attribute);
        }
    }
    return $data;
}

我如何扩展DOMNodeList / DOMXPath来做到这一点?

1 个答案:

答案 0 :(得分:1)

您可以做的是以下内容:

// create a wrapper class for DOMNodeList
class MyNodeList
{
  private $nodeList;

  public function __construct( DOMNodeList $nodeList ) {
    $this->nodeList = $nodeList;
  }

  // beware that this function returns a flat array of 
  // all desired attributes of all nodes in the list
  // how I think it was originally intended
  // But, since it won't be some kind of nested list,
  // I'm not sure how useful this actually is
  public function extract( $attributes ) {
    $attributes = (array) $attributes;
    $data = array();

    foreach( $this->nodeList as $node ) {
      foreach( $attributes as $attribute ) {
        $data[] = $node->getAttribute( $attribute);
      }
    }

    return $data;
  }
}

// extend DOMXPath
class MyXPath
  extends DOMXPath
{
  // override the original query() to wrap the result
  // in your MyNodeList, if the original result is a DOMNodeList
  public function query( $expression, DOMNode $contextNode = null, $registerNodeNS = true ) {
    $result = $this->xpath()->query( $expression, $contextNode, $registerNodeNS );
    if( $result instanceof DOMNodeList ) {
      $result = new MyNodeList( $result );
    }

    return $result;
  }
}

示例用法几乎与原始代码完全相同,除非您实例化MyXPath而不是DOMXPath

$aHref = ( new MyXPath( $domDoc ) )->query( 'descendant-or-self::base' )
                                   ->extract( array( 'href' ) );