J'utilise cette requête XPath pour sélectionner des éléments qui n'ont pas les descendants d'entrée dans un document Xhtml:Comment sélectionner uniquement les "nœuds supérieurs" dans cette requête XPath?
//*[not(descendant-or-self::input | descendant-or-self::textarea | descendant-or-self::select | ancestor::select)]
Avec l'exemple suivant le document XHtml:
<html>
<head>
<title>Title</title>
</head>
<body>
<div id="one">
<input type="text" />
</div>
<div id="two">
<textarea></textarea>
</div>
<div id="three">
<div id="four">
Text
</div>
</div>
<div id="five">
<select>
<option>One</option>
<option>Two</option>
</select>
</div>
<div id="six">
<input type="text" />
</div>
<div id="seven">
<div id="eight"></div>
</div>
</body>
</html>
... Et ce PHP Code:
// Populate $html and $query with above
$dom = new DOMDocument('1.0', 'UTF-8');
$dom->loadXML($html);
$xpath = new DOMXPath($dom);
$nodes = $xpath->query($query);
foreach($nodes as $node)
{
echo $node->tagName;
if($node->hasAttribute('id'))
echo '#' . $node->getAttribute('id');
echo ' ';
}
Je reçois ceci: head title div#three div#four div#seven div#eight
Mais je veux à la place: head div#three div#seven
Je vais prendre les résultats de la requête XPath et supprimer les éléments de DOMDocument. title div#four div#eight
sont des enfants de head div#three div#seven
, qui sont déjà dans le résultat.
En gardant à l'esprit cette requête sera utilisée sur n'importe quel document XHtml, comment pourrais-je changer ma requête XPath 1.0 pour obtenir les résultats souhaités?
Cela fonctionne! Il semble qu'il suffise que la condition répétée soit 'et (../descendant::input | ../descendant::textarea | ../ descendant :: select)'. La partie 'ancestor-or-self :: select' de la première condition garantit que l'intérieur de' select' est laissé seul. La partie '../', si je comprends bien, sélectionne le "parent racine", ce qui est exactement ce que je voulais, merci :). J'ai également ajouté un repli pour sélectionner le noeud racine, 'html', s'il n'y a pas d'éléments de champ. – Luke
J'ai découvert un problème avec la requête ne fonctionnait pas lorsque l'attribut 'xmlns' était présent sur l'élément' html'. Pour quelque raison que ce soit, vous ne pouvez pas simplement faire '$ xpath-> registerNamespace (NULL, 'http://www.w3.org/1999/xhtml')' ... Donc, vous devez remplacer 'NULL' par' ' 'html'' et faire '$ query = str_replace (' :: ',' :: input: ', $ query)' quand le xmlns est présent. Vous pouvez utiliser '$ xmlns = $ document-> lookupNamespaceURI (NULL)' pour voir s'il est présent. J'aimerais qu'il y ait un meilleur moyen. S'il y a, s'il vous plaît faites le moi savoir! – Luke