代码之家  ›  专栏  ›  技术社区  ›  rr.

PHP DOMElement::getElementsByTagName-是否只获取直接匹配的子级?

  •  7
  • rr.  · 技术社区  · 14 年前

    <category>
        <id>1</id>
        <name>Top Level Category Name</name>
        <subCategory>
            <id>2</id>
            <name>Sub Category Name</name>
        </subCategory>
        ...
    </category>
    

    如果我有一个代表顶级类别的DOMElement,

    $topLevelCategoryElement->getElementsByTagName('id');
    

    4 回复  |  直到 14 年前
        1
  •  18
  •   Artefacto    14 年前

    恐怕不行。您必须遍历子对象或使用XPath。

    for ($n = $parent->firstChild; $n !== null; $n = $n->nextSibling) {
        if ($n instanceof DOMElement && $n->tagName == "xxx") {
            //...
        }
    }
    

    XPath和XML文件示例:

    $xml = ...;
    $d = new DOMDocument();
    $d->loadXML($xml);
    $cat = $d->getElementsByTagName("subCategory")->item(0);
    $xp = new DOMXpath($d);
    $q = $xp->query("id", $cat); //note the second argument
    echo $q->item(0)->textContent;
    

    给予 2 .

        2
  •  13
  •   JLRishe    12 年前

    像这样的事情应该可以

    /**
     * Traverse an elements children and collect those nodes that
     * have the tagname specified in $tagName. Non-recursive
     *
     * @param DOMElement $element
     * @param string $tagName
     * @return array
     */
    function getImmediateChildrenByTagName(DOMElement $element, $tagName)
    {
        $result = array();
        foreach($element->childNodes as $child)
        {
            if($child instanceof DOMElement && $child->tagName == $tagName)
            {
                $result[] = $child;
            }
        }
        return $result;
    }
    

    编辑 :添加了DomeElement检查的实例

        3
  •  2
  •   Nick Bastin    14 年前

    specified the W3C ,任何节点对象上都需要有childNodes属性。您应该能够遍历所有直接子对象并测试它们的标记名,以查看它们是否就是您要查找的对象。根据树的外观,这可能比按标记名获取所有元素并测试它们的树位置要慢,也可能要快得多。

        4
  •  -1
  •   MerlinTheMagic    10 年前

    可以使用===比较元素。这将避免实例化Xpath对象。

    $dom = new DOMDocument();
    $dom->loadXML($xmlString);
    
    $return          = array();
    
    //find your top level element
    $topLevelElement = $dom->getElementsByTagName('category');
    //find all `id` child elements recursively
    $idElements      = $topLevelElement->getElementsByTagName('id');
    
    if ($idElements->length > 0) {
        foreach ($idElements as $idElement) {
            if ($idElement->parentNode === $topLevelElement) {
                $return[]   = $idElement;
           }
        }
    }
    
    //$return now holds non nested child elements