2010-04-23 7 views
2

XML:Testez d'abord sous-nœud du nœud

<mode> 
     <submode>1</submode> 
     <submode>2</submode> 
     <submode>3</submode> 
     <submode>4</submode> 
     <submode>5</submode> 
     <submode>6</submode> 
     <submode>7</submode> 
    </mode> 
    <mode> 
     <submode>7</submode> 
     <submode>8</submode> 
     <submode>9</submode> 
     <submode>10</submode> 
     <submode>11</submode> 
     <submode>12</submode> 
     <submode>13</submode> 
    </mode> 
    <mode> 
     <submode>14</submode> 
     <submode>15</submode> 
     <submode>16</submode> 
     <submode>17</submode> 
     <submode>18</submode> 
     <submode>19</submode> 
     20</submode> 
    </mode> 

Comment tester d'abord <submode> de chaque <mode> (j'ai besoin obtenir des chiffres: 1, 7, 14) dans cette construction:

<xsl:template match="submode"> 
    <xsl:if test="(parent::mode) and (...what?...)"> 
     ... 
    </xsl:if> 
    ... 
</xsl:template> 

Je ne comprends pas comment utiliser la position() ici.

Répondre

5

Il est généralement pas vrai que

position() = 1

est évaluée à true() si le noeud courant a un mode parent et le noeud courant est le premier submode enfant de son parent.

position() spécifie la position du noeud-liste courant et cela est défini d'une manière différente, en fonction de l'attribut select de <xsl:apply-templates> est spécifié.

Par exemple (en supposant que le XML fourni a un élément supérieur qui est le parent des mode éléments), si le modèle a été sélectionné lors de processingthe suivante:

<xsl:apply-templates select="/*/mode/submode[. = 3]"/>

puis

position() = 1

est vrai seulement pour le 3ème submode enfant du premier élément mode.

Une réponse correcte:

parent::mode and not(preceding-sibling::submode)

Ou, recommandé:

Avoir un modèle distinct:

<xsl:template match="mode/submode[1]">

Dans ce cas, pas de code avec dans le modèle est nécessaire de vérifier si le nœud actuel est le premier submode enfant - c'est déjà connu pour être ainsi.

+0

@Dimitre Novatchev, merci beaucoup, vous, comme toujours au top! Maintenant, je vais essayer de comprendre ce que vous avez écrit, mais le code fonctionne certainement (comme tout code de votre part). Mais si je "sépare le modèle" comme vous l'avez dit j'ai besoin de copier le code pour l'exécution de ' - je ne veux pas le faire. – Kalinin

0

Votre <xsl:template match= doit indiquer "mode/submode[1]".

Alors vous auriez le premier submode de chaque mode.

+0

@Jweede, je sais, mais je ne peux pas changer le '' parce qu'il ya plus de code pour le faire doit être exécutée en tout cas, non seulement pour la premier noeud dans 'submode'. – Kalinin

+0

Ensuite, vous pouvez ajouter plus de modèles, comme ce que recommande Dimitre. –

1

Pour compter le nombre de submode s dans la mode précédente si et seulement si cela est la première submode du mode en cours, et d'éviter la duplication de code entre <xsl:template match="submode"> et <xsl:template match="submode[1]">:

<!-- Special processing for first submode --> 
<xsl:template match="submode[1]"> 
    <xsl:variable name="previousSubmodes" 
        select="count(../preceding-sibling::mode/submode)"/> 

    <!-- ... Do stuff with count ... --> 

    <!-- Perform regular submode processing --> 
    <xsl:call-template name="submode"/> 

</xsl:template> 

<!-- Regular processing for submodes --> 
<xsl:template match="submode" name="submode"> 
    <!-- ... Do whatever ... --> 
</xsl:template> 

Vous pouvez faire le traitement du compte à partir du modèle pour mode à la place. De cette façon, vous n'aurez pas besoin de traitement spécial pour le premier submode.

<xsl:template match="mode"> 
    <!-- ... Other processing ... --> 

    <xsl:variable name="previousSubmodes" 
        select="count(preceding-sibling::mode/submode)"/> 

    <!-- ... Do stuff with count ... --> 

    <!-- Handle submodes; could use select="node()|@*" instead to process 
     everything, not just submodes --> 
    <xsl:apply-templates select="submode"/> 

</xsl:template> 

<xsl:template match="submode"> 
    <!-- ... Do whatever ... --> 
</xsl:template> 
Questions connexes