PHP DOM: How to get children by tag name in an elegant way?

I am parsing XML with the PHP DOM extension to store data in a different form. It is not at all surprising that when I parse an element, I quite often need to get all the children of a given name. There is a method DOMElement::getElementsByTagName($name), but it returns all descendants with this name, and not just children themselves. There is also a property DOMNode::$childNodes, but (1) it contains a list of nodes, not a list of elements, and even if I managed to turn the elements of the list into elements (2), I still need to check all of them for a name. Is there really no elegant solution to get only children of a certain name or am I missing something in the documentation?

Some illustration:

<?php

DOMDocument();
$document->loadXML(<<<EndOfXML
<a>
  <b>1</b>
  <b>2</b>
  <c>
    <b>3</b>
    <b>4</b>
  </c>
</a>
EndOfXML
);

$bs = $document
    ->getElementsByTagName('a')
    ->item(0)
    ->getElementsByTagName('b');

foreach($bs as $b){
    echo $b->nodeValue . "\n";
}

// Returns:
//   1
//   2
//   3
//   4
// I'd like to obtain only:
//   1
//   2

?>
+4
3

, , FilterIterator, . , DOMNodeList () DOMElementFilter Iterator Garden:

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

$bs = new DOMElementFilter($a->childNodes, 'b');

foreach($bs as $b){
    echo $b->nodeValue . "\n";
}

, :

1
2

DOMElementFilter . , * , , getElementsByTagName("*"). .

Hier - : https://eval.in/57170

+4

        $parent = $p->parentNode;

        foreach ( $parent->childNodes as $pp ) {

            if ( $pp->nodeName == 'p' ) {
                if ( strlen( $pp->nodeValue ) ) {
                    echo "{$pp->nodeValue}\n";
                }
            }

        }
+2

, :

(node) (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;
}

:

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

DOM node iso, ISO NL, . /.

:

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

DOM node, (root) node, . : , , . countries->country[ISO] - countries node .

0

All Articles