PHP DOM: How to get child elements by tag name in an elegant manner?

后端 未结 3 1544
有刺的猬
有刺的猬 2020-12-04 01:53

I\'m parsing some XML with PHP DOM extension in order to store the data in some other form. Quite unsurprisingly, when I parse an element I pretty often need to obtain all c

相关标签:
3条回答
  • 2020-12-04 02:27

    An elegant manner I can imagine would be using a FilterIterator that is suitable for the job. Exemplary one that is able to work on such a said DOMNodeList and (optionally) accepting a tagname to filter for as an exemplary DOMElementFilter from the Iterator Garden does:

    $a = $doc->getElementsByTagName('a')->item(0);
    
    $bs = new DOMElementFilter($a->childNodes, 'b');
    
    foreach($bs as $b){
        echo $b->nodeValue . "\n";
    }
    

    This will give the results you're looking for:

    1
    2
    

    You can find DOMElementFilter in the Development branch now. It's perhaps worth to allow * for any tagname as it's possible with getElementsByTagName("*") as well. But that's just some commentary.

    Hier is a working usage example online: https://eval.in/57170

    0 讨论(0)
  • 2020-12-04 02:28

    My solution used in a production:

    Finds a needle (node) in a haystack (DOM)

    function getAttachableNodeByAttributeName(\DOMElement $parent = null, string $elementTagName = null, string $attributeName = null, string $attributeValue = null)
    {
        $returnNode = null;
    
        $needleDOMNode = $parent->getElementsByTagName($elementTagName);
    
        $length = $needleDOMNode->length;
        //traverse through each existing given node object
        for ($i = $length; --$i >= 0;) {
    
            $needle = $needleDOMNode->item($i);
    
            //only one DOM node and no attributes specified?
            if (!$attributeName && !$attributeValue && 1 === $length) return $needle;
            //multiple nodes and attributes are specified
            elseif ($attributeName && $attributeValue && $needle->getAttribute($attributeName) === $attributeValue) return $needle;
        }
    
        return $returnNode;
    }
    

    Usage:

    $countryNode = getAttachableNodeByAttributeName($countriesNode, 'country', 'iso', 'NL');
    

    Returns DOM element from parent countries node by specified attribute iso using country ISO code 'NL', basically like a real search would do. Find a certain country by it's name in an array / object.

    Another usage example:

    $productNode = getAttachableNodeByAttributeName($products, 'partner-products');
    

    Returns DOM node element containing only single (root) node, without searching by any attribute. Note: for this you must make sure that root nodes are unique by elements' tag name, e.g. countries->country[ISO] - countries node here is unique and parent to all child nodes.

    0 讨论(0)
  • 2020-12-04 02:32

    simple iteration process

    $parent = $p->parentNode;
    
    foreach ( $parent->childNodes as $pp ) {
    
        if ( $pp->nodeName == 'p' ) {
    
            if ( strlen( $pp->nodeValue ) ) {
                echo "{$pp->nodeValue}\n";
            }
    
        }
    
    }
    
    0 讨论(0)
提交回复
热议问题