2010-12-08 12 views
2

J'ai du mal à obtenir que XSLT renvoie uniquement les valeurs de catégorie du XML. Pourquoi lastupdate et path sont-ils retournés? ... et comment puis-je arrêter cela? Merci d'avance.La sélection de Noeud explicite XSLT ne renvoie rien

document XML

<?xml version="1.0"?> 
<categories count="3"> 
    <lastupdate>08/12/2010 12:27</lastupdate> 
    <path>C:\</path> 
    <category>Music</category> 
    <category>News</category> 
    <category>Sport</category> 
</categories> 

Mon XSLT

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:template match="categories"> 
     <html> 
      <body> 
       <table border="0" cellpadding="0" cellspacing="0"> 
        <tbody> 
         <tr> 
          <td> 
           <xsl:apply-templates/> 
          </td> 
         </tr> 
        </tbody> 
       </table> 
      </body> 
     </html> 
    </xsl:template> 

    <xsl:template match="category"> 
     <a> 
      <xsl:value-of select="." /> 
     </a> 
    </xsl:template> 
</xsl:stylesheet> 

sortie HTML

<html> 
    <body> 
     <table border="0" cellpadding="0" cellspacing="0"> 
      <tbody> 
       <tr> 
        <td>08/12/2010 12:27C:\ 
         <a>Music</a> 
         <a>News</a> 
         <a>Sport</a> 
        </td> 
       </tr> 
      </tbody> 
     </table> 
    </body> 
</html> 
+0

Votre sortie suggère que ce n'est pas le plein xslt Vous êtes en train en cours d'exécution. Je soupçonne qu'il y a quelque chose de plus dans votre xslt qui copie 'lastupdate' et' path' à votre sortie. – Filburt

+0

Je suis d'accord. D'où vient la table? Ce n'est pas clair à partir de votre code affiché –

+0

A en juger par l'indentation dans son échantillon, il a omis la table entre le corps et les apply-templates, ce qui expliquerait aussi la sortie. – TToni

Répondre

1

Dans votre code vous postulez modèle pour tous les noeuds d'élément enfant categories.Voir http://www.w3.org/TR/xslt#built-in-rule

Ainsi vous avez besoin le code suivant:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output method="html" indent="yes" omit-xml-declaration="yes"/> 
    <xsl:template match="categories"> 
     <html> 
      <body> 
       <xsl:apply-templates select="category"/> 
      </body> 
     </html> 
    </xsl:template> 

    <xsl:template match="category"> 
     <a> 
      <xsl:value-of select="." /> 
     </a> 
    </xsl:template> 
</xsl:stylesheet> 

Pour obtenir ouput souhaitée:

<html> 
    <body> 
     <a>Music</a> 
     <a>News</a> 
     <a>Sport</a> 
    </body> 
</html> 
1

Votre < xsl: apply-templates /> applique tous les modèles correspondant à tous les sous-noeuds. Comme vous n'avez pas défini de modèles correspondants pour lastupdate et path, XSLT applique ses modèles par défaut, qui dans ce cas copient le contenu du texte.

Si vous voulez désactiver ceci, vous devez soit remplacer le (s) modèle (s) par défaut (normalement pas si bon) ou restreindre votre application de modèle sur les nœuds que vous voulez traiter. Dans votre exemple, élargir les apply-templates à

<xsl:apply-templates select="./category"/> 
+0

Vous avez écrit * remplacer le (s) modèle (s) par défaut (normalement pas si bon) *. Cela est faux: la plupart du temps, chaque transformation remplace une règle prédéfinie ... De même, démarrer l'étape '. /' Est verbeux et n'est pas nécessaire. –

+0

@Alejandro: Un modèle normal remplace une règle générale (par défaut) avec une règle spécifique qui s'applique uniquement à un certain sous-ensemble de nœuds. C'est parfaitement OK. Remplacer la règle par défaut par une règle qui s'applique à la même portée est dans mon expérience presque jamais nécessaire. J'ai inclus le "./" pour indiquer qu'il s'agit d'une instruction xpath, car l'OP ne semblait pas très expérimenté dans XSLT. Il peut avoir besoin de cette indication si le cas d'origine est plus compliqué que son exemple :-) – TToni

+0

La règle d'indentité (très souvent utilisée) remplace la règle intégrée des attributs. –

0

Serait-ce que vous avez quelque chose comme ça quelque part au fond de votre xslt:

<xsl:template match="@* | node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@* | node()"/> 
    </xsl:copy> 
</xsl:template> 

Cela expliquerait pourquoi vous vous retrouvez avec ces valeurs quelque part au milieu ouf votre sortie.

+0

XSLT définit des modèles par défaut pour les nœuds, les attributs et les nœuds de texte, qui sont lancés ici via l'appel général . Ils sont toujours là jusqu'à l'annulation. Si vous appliquez le XSLT dans son échantillon au XML, vous obtiendrez la sortie décrite (à l'exception des balises de table manquantes) – TToni

3

Pourquoi lastupdate et le chemin sont renvoyés?

Parce que built-in rules précisément ces deux:

<xsl:template match="*|/"> 
    <xsl:apply-templates/> 
</xsl:template> 

<xsl:template match="text()|@*"> 
    <xsl:value-of select="."/> 
</xsl:template> 

vide apply-templates est le même que celui ayant select="node()". Ensuite, les éléments lastupdate et path sont mis en correspondance par la règle intégrée pour les éléments (il suffit d'appliquer des modèles aux nœuds enfants) et leurs nœuds de texte enfants sont mis en correspondance par la règle intégrée pour les nœuds de texte.

... et comment puis-je arrêter cela?

Ecraser l'un des construit dans les règles comme:

<xsl:template match="text()"/> 

Signification pas de sortie de nœud de texte. Ou utiliser une approche de style push comme

<xsl:template match="categories"> 
<html> 
    <body> 
    <xsl:apply-templates select="category"/> 
    </body> 
</html> 
</xsl:template> 
+0

+1 pour un coreect (et la meilleure réponse). –

Questions connexes