9

データを他の形式で保存するために、PHP DOM拡張機能を使用してXMLを解析しています。当然のことながら、要素を解析するときに、ある名前のすべての子要素を取得する必要があることがよくあります。メソッドがありますが、DOMElement::getElementsByTagName($name)直接の子だけでなく、その名前を持つすべての子孫を返します。プロパティもありますDOMNode::$childNodesが、(1)要素リストではなくノードリストが含まれており、リスト項目を要素に変換できたとしても(2)それらすべての名前を確認する必要があります。特定の名前の子のみを取得するためのエレガントなソリューションは本当にありませんか、それともドキュメントに何かが欠けていますか?

いくつかの例:

<?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 に答える 3

3

私が想像できるエレガントなマナーはFilterIterator、仕事に適した を使用することです. そのような発言に取り組むことができ、(オプションで) Iterator GardenからのDOMNodeList例としてフィルタリングするタグ名を受け入れることができる模範的なものは、次のことを行い ます。DOMElementFilter

$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

于 2013-10-24T15:17:29.013 に答える
-1

プロダクションで使用される私のソリューション:

干し草の山 (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');

iso基本的に実際の検索と同じように、国ISOコード「NL」を使用して、指定された属性によって親国ノードからDOM要素を返します。配列/オブジェクト内の名前で特定の国を見つけます。

別の使用例:

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

属性で検索せずに、単一 (ルート) ノードのみを含む DOM ノード要素を返します。注: このためには、ルート ノードが要素のタグ名で一意であることを確認する必要があります。たとえば、ここcountries->country[ISO]countriesノードは一意であり、すべての子ノードの親です。

于 2018-02-15T14:41:17.180 に答える