关于xml:PHP中的DOMNode到DOMElement

 2021-04-09 

DOMNode to DOMElement in php

我想将DOMNode对象从对getElementsByTagName()的调用转换为DOMElement,以便访问子元素上的getElementsByTagName()之类的方法。用任何其他语言,我都会进行转换,这很容易,但是经过一番快速浏览,PHP没有进行对象转换。所以我需要知道的是如何从DOMNode对象中获取DOMElement对象。


您无需执行任何操作,只需调用以下方法:

1
2
3
4
5
$links = $dom->getElementsByTagName('a');

foreach ($links as $link) {
    $spans = $link->getElementsByTagName('span');
}

顺便说一句,DOMElementDOMNode的子类。如果您正在谈论DOMNodeList,则可以使用上述foreach()循环,或者通过使用DOMNodeListitem()方法,来访问此类列表中的元素。铅>

1
$link_0 = $dom->getElementsByTagName('a')->item(0);


这是我在项目中用来最小化IDE警告的方法。

1
2
3
4
5
6
7
8
9
10
11
/**
 * Cast a DOMNode into a DOMElement
 */

    function cast_e(DOMNode $node) : DOMElement {
    if ($node) {
        if ($node->nodeType === XML_ELEMENT_NODE) {
            return $node;
        }
    }
    return null;
}

我知道这主要是一个令人讨厌的IDE问题。

原因是$DOMNodeList->item(0)巫婆返回了DOMNode(或者至少是IDE认为如此)。

要解决此问题,您必须将$DOMDocument->getElementsByTagName( $tagName )->item($index)提取到自己的方法中。在DOCBlock中,将@return语句设置为DOMElement可以修复检查问题。

这至少在PHPStorm中有效。


您不需要进行任何显式的类型转换,只需检查DOMNode对象的nodeType是否为XML_ELEMENT_NODE

PHP对此将非常满意。

如果使用PHPLint检查代码,则会注意到PHPLint抱怨在DOMNode对象上使用getElementsByTagName。要解决此问题,您需要跳过以下箍:

1
2
/*.object.*/ $obj = $node;
$element = /*.(DOMElement).*/ $obj;

然后,您将拥有正确类型的$ element变量,并且PHPLint没有投诉。


如果有人正在IntelliJ / PHPStorm中寻找更优雅的解决方案。我设法解决了这样的问题:

1
2
3
4
5
6
7
8
9
10
    private function doSomething(DOMNode $child){
       
        if(!$child instanceof DOMElement)
            throw new Exception('DOMElement expected but got something else.');
       
        $attr = $child->getAttribute('attr'); //recognized by PHPStorm now as DOMElement
       
        /* and more code */
       
    }

我所有的代码都正确地假设DOMNode是DOMElement的超类,但也是DOMComment等。例如,当我需要DOMElement来使用getAttribute时,我会添加上面的check。