简体   繁体   English

php 中的 DOMNode 到 DOMElement

[英]DOMNode to DOMElement in php

I want to convert a DOMNode object from a call to getElementsByTagName() to a DOMElement in order to access methods like getElementsByTagName() on the child element.我想将DOMNode对象从对getElementsByTagName()的调用转换为DOMElement ,以便访问子元素上的getElementsByTagName()等方法。 In any other language, I would cast and it would be easy, but after some quick looking, PHP does not have object casting.在任何其他语言中,我会强制转换并且这很容易,但是经过快速查看后,PHP 没有对象转换。 So what I need to know is how to get a DOMElement object from a DOMNode object.所以我需要知道的是如何从DOMNode对象中获取DOMElement对象。

You don't need to cast anything, just call the method:您不需要强制转换任何内容,只需调用该方法:

$links = $dom->getElementsByTagName('a');

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

And by the way, DOMElement is a subclass of DOMNode .顺便说一下, DOMElementDOMNode的子类。 If you were talking about a DOMNodeList , then accessing the elements in such a list can be done, be either the method presented above, with a foreach() loop, either by using the item() method of DOMNodeList :如果您正在谈论DOMNodeList ,那么可以访问此类列表中的元素,可以使用上面介绍的方法,使用foreach()循环,或者使用DOMNodeListitem()方法:

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

This is what I use in my project to minimize IDE warning.这是我在我的项目中用来最小化 IDE 警告的方法。

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

You don't need to do any explicit typecasting, just check if your DOMNode object has a nodeType of XML_ELEMENT_NODE .您不需要进行任何显式类型转换,只需检查您的 DOMNode 对象是否具有XML_ELEMENT_NODE的 nodeType 。

PHP will be perfectly happy with this. PHP 会对此非常满意。

If you use PHPLint to check your code you will notice that PHPLint complains about using getElementsByTagName on a DOMNode object.如果您使用PHPLint检查您的代码,您会注意到 PHPLint 抱怨在 DOMNode 对象上使用getElementsByTagName To get around this you need to jump through the following hoop:要解决这个问题,您需要跳过以下环节:

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

Then you will have a $element variable of the correct type and no complaints from PHPLint.然后您将拥有一个正确类型的 $element 变量并且没有来自 PHPLint 的抱怨。

I know this is mostly an annoying IDE problem.我知道这主要是一个烦人的 IDE 问题。

The reason is $DOMNodeList->item(0) witch returns a DOMNode ( or at least the IDE thinks so ).原因是$DOMNodeList->item(0)女巫返回一个 DOMNode (或者至少 IDE 是这么认为的)。

To fix this you will have to Extract out the $DOMDocument->getElementsByTagName( $tagName )->item($index) into a method of its own.要解决此问题,您必须将$DOMDocument->getElementsByTagName( $tagName )->item($index)提取到它自己的方法中。 In the DOCBlock you set the @return statement to DOMElement witch fixes the inspection problem.在 DOCBlock 中,您将 @return 语句设置为 DOMElement 以修复检查问题。

This Works at least in PHPStorm.这至少在 PHPStorm 中有效。

If anyone is looking for a more elegant solution in IntelliJ/PHPStorm .如果有人在IntelliJ/PHPStorm 中寻找更优雅的解决方案。 I managed to solve the issue like this:我设法解决了这样的问题:

    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 */
        
    }

All my code corretly assumes DOMNode which is de super class of DOMElement but also DOMComment etc. When I need DOMElement to use getAttribute for example, then I add above check.我所有的代码都正确地假设 DOMNode 是 DOMElement 的超类,但也是 DOMComment 等。当我需要 DOMElement 使用getAttribute ,例如,我添加上面的检查。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM