2010-03-21 5 views
6

J'ai un document qui ressemble àPuis-je créer dynamiquement cette requête XPath dans XSLT?

<root> 
    <element> 
     <subelement1 /> 
     <subelement2 /> 
    </element> 
    <element> 
     <subelement2 /> 
     <subelement1 /> 
    </element> 
</root> 

Dans ma feuille XSLT dans le contexte de /element[2]/[someNode] Je veux obtenir un numéro qui représente la distance de /element[1]/[someNode] (à savoir le nombre de frères et sœurs précédents de /element1/[someNode]). Par exemple, dans le contexte de /element[2]/subelement1 je voudrais avoir un moyen d'obtenir le numéro 2, la distance de /element[1] à /element[1]/subelement2. J'ai seulement besoin de la distance du nom de noeud donné de la première instance de <element>.

Intuitivement Je pensais que je pouvais construire cela comme

<xsl:variable name="nodename" select="name()" /> 
<xsl:value-of select="/element[1]/$nodename/preceding-sibling::*" /> 

mais malheureusement cette fiche ne compile pas. Est ce que j'essaye de réaliser possible dans XSLT?

+0

Votre exemple semble inconsistent: dans le contexte de '/ element [2]/[someNode]' vous voulez trouver '/ element [1]/[someNode]' avec comme exemple dans '/ element [2]/subelement1' vous voulez trouver le distance de '/ element [1]' à '/ element [1]/sous-élément 2' - est-ce que [someNode] est ici subelement2 ou subelement1? –

+0

Voir aussi http://stackoverflow.com/questions/4630023/dynamic-xpath-in-xslt – Vadzim

Répondre

8
  1. Vous ne pouvez pas utiliser une variable XSLT comme l'axe d'un XPATH instruction, mais vous pouvez l'utiliser dans un filtre de prédicat. Ainsi, si vous deviez correspondre à un élément (par exemple, *), puis le limiter aux éléments dont le nom() est égal à la valeur stockée dans votre variable (c'est-à-dire *[name()=$nodename]), l'XPATH sera valide. L'XPATH que vous construisiez renverrait la valeur de l'élément correspondant. Si vous souhaitez renvoyer le nombre d'éléments correspondant à ce modèle, vous pouvez utiliser la fonction count(). Votre exemple XML a un élément de document <root>, mais votre XPATH n'inclut pas <root>.

Cela renvoie le nombre d'éléments preceding-sibling en utilisant la variable affectée par le noeud contextuel:

<xsl:variable name="nodename" select="name()" /> 
<xsl:value-of select="count(/root/element[1]/*[name()=$nodename]/preceding-sibling::*)" /> 

Vous pouvez éliminer la variable et il suffit d'utiliser:

<xsl:value-of select="count(/root/element[1]/*[name()=name(current())]/preceding-sibling::*)" /> 
1

*[name() = $nodename] peut être ce que vous voulez au lieu de $nodename mais vous devriez alors mieux définir deux variables avec la valeur de nom local() et namespace-uri() et vérifier par exemple. *[local-name() = $localname and namespace-uri() = $namespaceuri] pour avoir un espace de noms sûr pour sélectionner les éléments.

0

La construction de xpath est malheureusement impossible. XPaths sont statiquement compilés; vous ne pouvez pas les générer à la volée (ou si vous le faites, ce ne sont que des chaînes et ne peuvent pas être exécutées).

Cependant, ce que vous pouvez faire est d'écrire une requête qui arrive à des références croisées plusieurs valeurs qui sont eux-mêmes dynamiques ...