Xpathを使用して特定のノードのテキストと属性の両方を取得する

StackOverflow https://stackoverflow.com/questions/141913

  •  02-07-2019
  •  | 
  •  

質問

PHPとxpathを使用したAPI呼び出しのXML結果を解析しています。

 $dom = new DOMDocument();
 $dom->loadXML($response->getBody());

 $xpath = new DOMXPath($dom);
 $xpath->registerNamespace("a", "http://www.example.com");

 $hrefs = $xpath->query('//a:Books/text()', $dom);

 for ($i = 0; $i < $hrefs->length; $i++) {
      $arrBookTitle[$i] = $hrefs->item($i)->data;
 }

 $hrefs = $xpath->query('//a:Books', $dom);

 for ($i = 0; $i < $hrefs->length; $i++) {
      $arrBookDewey[$i] = $hrefs->item($i)->getAttribute('DeweyDecimal');
 }

これは機能しますが、1つのクエリからテキストと属性の両方にアクセスできる方法はありますか?もしそうなら、クエリが実行された後、どのようにしてそれらのアイテムに行きますか?

役に立ちましたか?

解決

いくつかの辺りを見回した後、私はこのソリューションに出会いました。これにより、要素テキストを取得し、ノードの属性にアクセスできます。

$hrefs = $xpath->query('//a:Books', $dom);

for ($i = 0; $i < $hrefs->length; $i++) {
    $arrBookTitle[$i] = $hrefs->item($i)->nodeValue;
    $arrBookDewey[$i] = $hrefs->item($i)->getAttribute('DeweyDecimal');
}

他のヒント

&quot; a:Books&quot;の両方のテキストノードを選択する単一のXPath式。およびその「DeweyDecimal」属性は次のとおりです

// a:Books / text()| // a:Books / @ DeweyDecimal

上記の式でのXPathのユニオン演算子の使用に注意してください

別のメモ:&quot; //&quot;の使用は避けてくださいXMLドキュメント全体がトラバースされる可能性があるため、略語であるため、非常に高価です。 XMLドキュメントの構造がわかっている場合は常に、より具体的なXPath式(特定のロケーションステップのチェーンで構成されるなど)を使用することをお勧めします。

XMLドキュメントから値を取得するだけの場合は、 SimpleXML は、よりスリムで、高速で、メモリに優しいソリューションです:

$xml=simplexml_load_string($response->getBody());
$xml->registerXPathNamespace('a', 'http://www.example.com');
$books=$xml->xpath('//a:Books');
foreach ($books as $i => $book) {
    $arrBookTitle[$i]=(string)$book;
    $arrBookDewey[$i]=$book['DeweyDecimal'];
}

連結を照会できますか?

$xpath->query('concat(//a:Books/text(), //a:Books/@DeweyDecimal)', $dom);

XSLTはそれ自体が式言語であり、式内から必要な戻り値の特定の形式を構築できます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top