sélection XPath

7 réponses
Avatar
Une Bévue
en JavaScript, j'utilise XPath pour sélectionner des noeuds :
var snapshot =
document.evaluate("/html/body/div[@id='page_arborescence']/div[@class='dir']/div[@class='dir']/div[@class='dir']/div[@class='dir']/div[@class='images']/div[@class='boxwrapper']/div[@class='box']",
document.documentElement, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
null);

ça marche très bien, mais j'aimerais perfectionner cette expression.

en simplifiant, ma structure est ainsi :

<html>
<body>
<div>
<div>
<div class='box' data-path='un path' /> <!-- OK -->
[...]
<div class='box' data-path='le path recherché' /> <!-- OK -->
[...]
<div class='box' data-path='un autre path' /> <!-- OK -->
</div>
</div>
<div>
<div>
<div class='box' data-path='un path' /> <!-- PAS OK -->
[...]
<div class='box' data-path='le path NON recherché' /> <!-- PAS OK -->
[...]
<div class='box' data-path='un autre path' /> <!-- PAS OK -->
</div>
</div>
</body>
</html>


disons qu'il y a plusieurs "niches" de noeuds avec class='box' MAIS je
ne m'intéresse qu'aux noeuds qui sont dans la niche où le @data-path est
le path recherché, les autres ne m'intéressent pas.

comment n'obtenir que cette "niche" là ?

7 réponses

Avatar
SAM
Le 04/11/14 16:31, Une Bévue a écrit :
en JavaScript, j'utilise XPath pour sélectionner des noeuds :
var snapshot > document.evaluate("/html/body/div[@id='page_arborescence']/div[@class='dir']/div[@class='dir']/div[@class='dir']/div[@class='dir']/div[@class='images']/div[@class='boxwrapper']/div[@class='box']",
document.documentElement, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
null);

ça marche très bien, mais j'aimerais perfectionner cette expression.

en simplifiant, ma structure est ainsi :

<html>
<body>
<div>
<div>
<div class='box' data-path='un path' /> <!-- OK -->
[...]
<div class='box' data-path='le path recherché' /> <!-- OK -->
[...]
<div class='box' data-path='un autre path' /> <!-- OK -->
</div>
</div>
<div>
<div>
<div class='box' data-path='un path' /> <!-- PAS OK -->
[...]
<div class='box' data-path='le path NON recherché' /> <!-- PAS OK
-->
[...]
<div class='box' data-path='un autre path' /> <!-- PAS OK -->
</div>
</div>
</body>
</html>


disons qu'il y a plusieurs "niches" de noeuds avec class='box' MAIS je
ne m'intéresse qu'aux noeuds qui sont dans la niche où le @data-path est
le path recherché, les autres ne m'intéressent pas.

comment n'obtenir que cette "niche" là ?



En XPath ?
... no sè
mais en JS "normal" ce n'est pas si compliqué :

function getDivsDuBonPath(chemin) {
var dp = document.getElementsByTagName('*'), n = dp.length, d = [];
while(n--) if(dp[n].getAttribute('data-path')==chemin) d.push(dp[n]);
return d;
}

non ?

et puis, par exemple :

var d = getDivsDuBonPath('le path recherché'), n=d.length;
while(n--) document.body.appendChild(d[n].cloneNode(true));


Cordialement,
--
Stéphane Moriaux avec/with iMac-intel 27" & Mac OS X 10.6.8
Avatar
Une Bévue
Le 05/11/14 01:13, SAM a écrit :
non ?


non ;-)
Avatar
Une Bévue
Le 05/11/14 01:13, SAM a écrit :
non ?



non !

en fait la solution est très simple, c'est celle que j'avais intuitée et
qui m'a été confirmée par Alain Katterlin sur fr.comp.text.xml, je cite :

Ou bien peut-être par "niche" entends-tu <div>, et tu veux tous les
'box' dans la div qui contient la box avec data-path='recherché' ? Dans
ce cas, ce serait :

.../div[@class='box' and @data-path="le path recherché"]/../div

c'est-à-dire : quand on a atteint le data-path, on remonte, puis on
redescend sur tous les <div>. Si il y a des <div @¢lass="pas-box"> au
même niveau que les <div class="box"> il faut remettre le test sur box
en fin de chemin.



ça donne donc dans mon exact cas :
var snapshot =
document.evaluate("/html/body/div[@id='page_arborescence']/div[@class='dir']/div[@class='dir']/div[@class='dir']/div[@class='dir']/div[@class='images']/div[@class='boxwrapper']/div[@class='box'
and @id='<le path recherché']/../div[@class='box']",
document.documentElement, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
null);

simple comme bonjour !
Avatar
SAM
Le 05/11/14 05:09, Une Bévue a écrit :
Le 05/11/14 01:13, SAM a écrit :
non ?



non !



chez moi, avec ton exemple, je pense que ça fonctionne
(je suis sûr et certain : j'ai testé)

en fait la solution est très simple, c'est celle que j'avais intuitée et
qui m'a été confirmée par Alain Katterlin sur fr.comp.text.xml, je cite :

Ou bien peut-être par "niche" entends-tu <div>, et tu veux tous les
'box' dans la div qui contient la box avec data-path='recherché' ? Dans
ce cas, ce serait :

.../div[@class='box' and @data-path="le path recherché"]/../div

c'est-à-dire : quand on a atteint le data-path, on remonte, puis on
redescend sur tous les <div>. Si il y a des <div @¢lass="pas-box"> au
même niveau que les <div class="box"> il faut remettre le test sur box
en fin de chemin.





Je ne comprends rien à ces histoires de remontées et redescentes !

ça donne donc dans mon exact cas :
var snapshot > document.evaluate("/html/body/div[@id='page_arborescence']/div[@class='dir']/div[@class='dir']/div[@class='dir']/div[@class='dir']/div[@class='images']/div[@class='boxwrapper']/div[@class='box'
and @id='<le path recherché']/../div[@class='box']",
document.documentElement, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
null);

simple comme bonjour !




Ça n'a rien à voir avec l'exemple de code html donné précédemment !
Là ici, et si je comprends bien, on cherche "le path recherché"
*seulement* s'il est dans une *imbrication spécifique* de divs, non ???


Cordialement,
--
Stéphane Moriaux avec/with iMac-intel 27" & Mac OS X 10.6.8
Avatar
Une Bévue
Le 06/11/14 12:58, SAM a écrit :
Ça n'a rien à voir avec l'exemple de code html donné précédemment !
Là ici, et si je comprends bien, on cherche "le path recherché"
*seulement* s'il est dans une *imbrication spécifique* de divs, non ???



non on cherche toutes les divs de class 'box' qui sont dans la même div
que la div de class box ayant pour id un id donné.
Avatar
SAM
Le 07/11/14 05:01, Une Bévue a écrit :
Le 06/11/14 12:58, SAM a écrit :
Là ici, et si je comprends bien, on cherche "le path recherché"
*seulement* s'il est dans une *imbrication spécifique* de divs, non ???



non on cherche toutes les divs de class 'box' qui sont dans la même div
que la div de class box ayant pour id un id donné.



Comme il ne peut il y avoir qu'un seul ID de même nom, il n'est pas
difficile à trouver (qu'il lui soit ou non attribué une class 'box')


function getThatFckBoxes(leBonTruc) {
var i = document.getElementById(leBonTruc),
d = [];
i = i.parentNode;
while(i.tagName != 'div') i=i.parentNode;
i = i.getElementsByTagName('DIV');
for(var n=0, z=i.length; n<z; n++)
if(i[n].className=='box' &&
i[n].id!=leBonTruc)
d.push(i[n]);
return d;
}



Cordialement,
--
Stéphane Moriaux avec/with iMac-intel 27" & Mac OS X 10.6.8
Avatar
Une Bévue
Le 09/11/14 00:26, SAM a écrit :
function getThatFckBoxes(leBonTruc) {
var i = document.getElementById(leBonTruc),
d = [];
i = i.parentNode;
while(i.tagName != 'div') i=i.parentNode;
i = i.getElementsByTagName('DIV');
for(var n=0, z=i.length; n<z; n++)
if(i[n].className=='box' &&
i[n].id!=leBonTruc)
d.push(i[n]);
return d;
}



oui, ça doit rouler, merci !