2008-11-03 4 views
0

Je parcours un document XML, sélectionnant tous les éléments, et créant des liens basés sur l'ancêtre qui est habituellement deux nœuds dans l'arbre , mais occasionnellement 3 ou 4 nœuds vers le haut. Pour la majorité des éléments, l'utilisation de <xsl:value-of select="translate(../../@name,$uc,$lc)" /> fonctionne très bien, mais pour les cas où l'ancêtre a environ 3 nœuds, j'aimerais utiliser <xsl:value-of select="translate(ancestor::package/@name,$uc,$lc)" />, mais cela ne fonctionne pas. J'utilise xsltproc de Ruby pour faire mes transformations XSL.Sélection de l'attribut de l'ancêtre; "../ .." fonctionne, "ancestor :: <tagname>" ne fonctionne pas

arbre de l'échantillon (oui, il a XSLT, non, je ne suis pas essayer de le traiter):

<package name="blork!" xmlns="http://xml.snapin.com/XBL"> 
    <xsl:template name="doSomething"> 
    <tokens> 
     <token name="text-from-resource" export="public" /> 
    </tokens> 
    </xsl:template> 
</package> 

XSL J'utilise:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:s4="http://xml.snapin.com/XBL"> 
    <xsl:template match="/"> 
    <xsl:if test="count(//s4:token) >0"> 
     <xsl:text>Tokens!</xsl:text> 
     <xsl:for-each select="//s4:token"> 
     <xsl:choose> 
      <xsl:when test="@export='global'" /> 
      <xsl:otherwise> 
      <xsl:value-of select="translate(ancestor::s4:package/@name,$uc,$lc)" /> 
      </xsl:otherwise> 
     </xsl:choose> 
     </xsl:for-each> 
    </xsl:if> 
    </xsl:template> 
</xsl:stylesheet> 

Modifier : Ah, à droite, j'ai oublié l'espace de noms sur le select. L'analyseur trouve cet ancêtre correctement dans la plupart des cas, mais il ne peut toujours pas le trouver quand il y a un nœud xsl: et le fichier cible n'a pas d'espace de nom pour xsl. Je préférerais ne pas modifier le fichier cible, parce que c'est le code de production --- J'écris juste un outil autodoc.

+0

La 2ème option ci-dessous a-t-elle fonctionné pour vous? Il peut y avoir des problèmes lorsque les jetons sont imbriqués dans un élément xsl. Je ne suis pas sûr que les éléments internes retournent à l'espace de noms par défaut, auquel cas vous ne trouverez peut-être même pas les éléments jetons. –

Répondre

3

Votre problème est probablement lié à l'espace de noms. Vous n'avez pas inclus ceux dans l'arbre d'échantillonnage - pouvez-vous être un peu plus précis dans ce que vous avez collé? En supposant que le nœud du paquet est dans le même espace que le noeud jeton, essayez:

<xsl:value-of select="translate(ancestor::s4:package/@name,$uc,$lc)" /> 

Vous pouvez également tester simplement le nom non qualifié, mais il sera plus lent:

<xsl:value-of select="translate(ancestor::*[local-name()='package']/@name,$uc,$lc)" /> 

W3C nom local () spec here.

1

Je pense qu'il est impossible de déclarer l'espace de noms pour le préfixe 'xsl' dans le document cible tant que vous utilisez des processeurs XML prenant en compte l'espace de noms. N'avez-vous vu aucune erreur lorsque vous essayez de transformer le document cible avec xsltproc et la feuille de style donnée?

0

Vous pouvez vérifier quelle version de XSLT vos outils utilisent. Je crois que XSLT 1.0 ne supporte pas "ancestor :: <tag> ..."