2009-03-26 8 views
0

Je travaille sur un script Greasemonkey qui doit fonctionner sur chaque noeud entre deux autres. Actuellement, je reçois le premier noeud en utilisant une expression XPath (de plus en plus compliquée). J'ai une autre expression pour obtenir les nœuds "between", mais il contient deux fois l'expression initiale et devient plutôt long. Voici une version antérieure qui ne contenait deux « clauses »:Obtenir tous les nœuds entre le nœud actuel et un autre sans courant()?

var xpHeader = "//h2[a/@name='section-References' or a/@name='References']"; 
var xpContents = "//h2[a/@name='section-References' or a/@name='References']/following-sibling::*[following-sibling::h2[1] = //h2[a/@name='section-References' or a/@name='References']/following-sibling::h2[1]]" 

Ce que je suis à la recherche est un moyen de sélectionner le « contenu » à partir d'un nœud de contexte plutôt que Réintégration l'expression originale à plusieurs reprises - que " header "L'expression va devenir beaucoup plus complexe très rapidement. Je sais que cela peut être fait en XSLT en utilisant la fonction current(), mais bien sûr, ce n'est pas disponible en XPath vanille: Comme je tape cela, il me vient

<xsl:template match="//h2[a/@name='section-References' or a/@name='References']"> 
    <xsl:for-each select="following-sibling::*[following-sibling::h2[1] = current()/following-sibling::h2[1]]"> 
     <!-- do stuff --> 
    </xsl:for-each> 
</xsl:template> 

qu'à ce stade, il serait probablement plus facile à utiliser le DOM pour recueillir le contenu plutôt que XPath, mais je suis toujours intéressé de savoir si c'est quelque chose qui peut être fait.

La version originale du script est available on UserScripts.org.

+0

Il n'est pas productif si le document XML sur lequel les expressions XPath sont exécutées n'est pas fourni. Personne ne peut même comprendre ce que les expressions XPath de la question sélectionnent. Comment peut-on s'attendre à ce que quelqu'un fournisse une solution? Je suis sur le point de downvoting, sinon édité. –

+0

... le lien fourni contient à la fois la source complète et des liens vers des documents de test. Que veux-tu de plus? –

+0

Il n'y a pas de document XML sur le lien fourni!Comment écrirait-on une expression XPath pour sélectionner quelque chose d'inconnu? –

Répondre

2

Bien que vous écrivez des expressions XPath, pour Javascript, ce ne sont que des chaînes. Vous pouvez concaténer des chaînes. Maintenant, votre expression d'en-tête peut devenir aussi compliquée que vous voulez sans affecter la complexité de l'affectation de l'expression de contenu. L'évaluateur XPath devra toujours analyser la chaîne entière, et s'il n'y a pas d'optimisation de la requête, alors il peut être évalué plusieurs fois, mais même cela peut être assez rapide pour que cela n'a pas d'importance.

+0

Ce n'est pas une mauvaise idée. Cela répond certainement au problème de maintenance. :-) –

1

Vous pouvez utiliser jQuery ou un autre framework JavaScript pour faciliter le travail avec le DOM.

Exemple:

// ==UserScript== 
// @name   MyScript 
// @namespace  http://example.com 
// @description Example 
// @include  * 
// 
// @require  http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js 
// ==/UserScript== 

$('h2[some crazy attributes...]').each(function() { 
    // Do something 
}); 

Vérifiez la référence jQuery pour plus d'informations sur la sélection et la traversée des éléments DOM via des attributs XPath.

jQuery Selectors

jQuery Traversal

jQuery next()

jQuery nextAll()

2

Il semble que l'utilisation du DOM sera un peu plus facile, une fois que vous utilisez XPath pour recueillir les choses à ce niveau. En supposant que vous utilisez pas de cadre, quelque chose le long des lignes de:

var nodes = document.evaluate("//h2[a/@name='section-References' or a/@name='References']/following-sibling::*", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); 
var contents=[]; 
if (nodes.snapshotLength>0) contents.push(new Array()); 
var currentGroup=0; 
for (var i=0;i<nodes.snapshotLength;i++) { 
    if (nodes.shapshotItem(i)==<your favorite way to detect the right flavor of h2 element>) { 
    currentGroup++; 
    contents.push(new Array()); 
    continue; 
    } 
    contents[currentGroup].push(nodes.snapshotItem(i)); 
} 

Il est un peu bavard, mais vous vous retrouverez avec un tableau de tableaux d'éléments entre les nœuds h2 intéressants.

Questions connexes