2009-08-12 5 views
2

Je dois restituer un nombre spécifié d'éléments à partir d'une source XML, où les éléments "DueDate" ne sont pas exportés. Voici un exemple de xml:Comment rendre un nombre limité d'éléments dans XSLT?

<Items> 
    <Item> 
    <Title>Title 1</Title> 
    <DueDate>01-02-2008</DueDate> 
    </Item> 
    <Item> 
    <Title>Title 2</Title> 
    <DueDate>01-02-2009</DueDate> 
    </Item> 
    <Item> 
    <Title>Title 3</Title> 
    <DueDate>01-02-2010</DueDate> 
    </Item> 
    <Item> 
    <Title>Title 4</Title> 
    <DueDate>01-02-2011</DueDate> 
    </Item> 
    <Item> 
    <Title>Title 5</Title> 
    <DueDate>01-02-2012</DueDate> 
    </Item> 
    <Item> 
    <Title>Title 6</Title> 
    <DueDate>01-02-2013</DueDate> 
    </Item> 
</Items> 

Le nombre d'éléments à afficher et la date sont transmis au XSLT paramaters. Est-il possible de compter le nombre d'éléments rendus dans une boucle for-each dans Xslt? Ou y a-t-il une meilleure approche?

Un exemple pourrait être que la limite a été fixée à 3 éléments. Dans cet exemple, je m'attendrais à voir les résultats suivants: "Titre 3", "Titre 4" et "Titre 5".

Répondre

0

Le principal problème est que votre XML d'entrée ne se conforme pas au format utile "aaaa-mm-jj. Cela rend le tri/filtrage de ces éléments une douleur dans le cul derrière.

Si je vous comprends bien, vous devez

  • filtre sur la date d'échéance première
  • appliquent un maximum à la sortie après

XPath pour sélectionner tous les <Item> s jusqu'à une certaine date d'échéance maximale irait comme suit:

Item[ 
    substring-before(DueDate, '-') 
    &lt;= 
    substring-before($MaxDueDate, '-') 

    and 

    substring-before(substring-after(DueDate, '-'), '-') 
    &lt;= 
    substring-before(substring-after($MaxDueDate, '-'), '-') 

    and 

    substring-after(substring-after(DueDate, '-'), '-') 
    &lt;= 
    substring-after(substring-after($MaxDueDate, '-'), '-') 
][ 
    position() &lt;= $MaxCount 
] 

Maintenant, comparez cela à la façon triviale, si vous aviez « aaaa-mm-jj » dates:

Item[ 
    DueDate &lt;= $MaxDueDate 
][ 
    position() &lt;= $MaxCount 
] 

Ainsi, pour ne copier que ces éléments, vous iriez:

<xsl:template match="Items"> 
    <xsl:copy> 
    <xsl:copy-of select=" 
     { the expression I gave above } 
    " /> 
    </xsl:copy> 
</xsl:template> 

Pour les valeurs des paramètres de '01-02-2012' et 4, respectivement, je reçois:

<Items> 
    <Item> 
    <Title>Title 1</Title> 
    <DueDate>01-02-2008</DueDate> 
    </Item> 
    <Item> 
    <Title>Title 2</Title> 
    <DueDate>01-02-2009</DueDate> 
    </Item> 
    <Item> 
    <Title>Title 3</Title> 
    <DueDate>01-02-2010</DueDate> 
    </Item> 
    <Item> 
    <Title>Title 4</Title> 
    <DueDate>01-02-2011</DueDate> 
    </Item> 
</Items> 
1

Essayez d'imbrication ce dans un xsl standard pour-chaque n dans votre cas est 3:

<xsl:if test="position() &lt; n"> 

Mais si vous voulez également vérifier la date alors vous aurez besoin nicher une autre si et créer des dates dans le format yyyyMMdd qui peut être comparé numériquement comme ceci:

<xsl:variable name="secondDate" select="concat(substring(submissionDeadline, 1,4),substring(submissionDeadline, 6,2),substring(submissionDeadline, 9,2))"/> 

<xsl:if test="$firstDate &gt; $secondDate"> 
4

Vous pouvez faire quelque chose comme ceci. Faites-en un modèle que vous pouvez appeler avec paramters:

<xsl:template match="/"> 
<xsl:variable name="count" select="3"/> 

<xsl:for-each select="Items/Item"> 
    <xsl:if test="position() &lt; $count"> 
     <xsl:value-of select="Title"/> - <xsl:value-of select="DueDate"/> 
    </xsl:if> 
</xsl:for-each> 

+0

Mais cela ne supprimera pas les éléments où la « DueDate » est supérieure à aujourd'hui? Cela me donnera juste les trois premiers éléments! Si j'insère une instruction if pour vérifier la date, seul l'élément thrid (position() == 3) "valid" est affiché. –

Questions connexes