2010-09-05 6 views
5

J'utilise XSLT1.0 pour transformer mon XML.Vérification du caractère de départ devrait être « T » et suivant 3 caractère devrait être le numéro dans xslt

je rencontre ci-dessous Tabs.xml

<?xml version="1.0"?> 
<tcm:ListItems xmlns:tcm="http://www.tridion.com/ContentManager/5.0" ID="tcm:481-87289-4" Managed="68"> 
    <tcm:Item ID="tcm:481-596728-64" Title="T000. Brisbane" pageURL="/australia/brisbane/index.aspx" componentTitle="Overview"/> 
    <tcm:Item ID="tcm:481-598671-64" Title="Tabs XML"/> 
    <tcm:Item ID="tcm:481-598672-64" Title="T030 Special Offers" pageURL="/australia/brisbane/specialoffers.aspx" componentTitle="Special Offers"/> 
    <tcm:Item ID="tcm:481-598673-64" Title="020 Flight Schedules" pageURL="/australia/brisbane/flightschedules.aspx" componentTitle="Flight Schedules"/> 
    <tcm:Item ID="tcm:481-598674-64" Title="T010 Guide" pageURL="/australia/brisbane/guide.aspx" componentTitle="Guide"/> 
</tcm:ListItems> 

Et je me sers ci-dessous xslt pour le transformer!

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:tcm="http://www.tridion.com/ContentManager/5.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:em="http://www.emirates.com/tridion/schemas" xmlns:tcmse="http://www.tridion.com/ContentManager/5.1/TcmScriptAssistant" exclude-result-prefixes="em xlink tcmse tcm"> 
    <xsl:output method="xml" version="1.0" encoding="UTF-16" indent="yes"/> 
    <xsl:template match="tcm:ListItems"> 
    <list type="Tabs"> 
     <xsl:apply-templates select="tcm:Item"> 
     <xsl:sort select="@Title" order="ascending"/> 
     </xsl:apply-templates> 
    </list> 
    </xsl:template> 
    <!-- add field values for each item--> 
    <xsl:template match="tcm:Item"> 
    <xsl:if test="@componentTitle != ''"> 
     <xsl:element name="tab"> 
     <xsl:attribute name="id"> 
      <xsl:value-of select="substring-after(@ID, '-')"/> 
     </xsl:attribute> 
     <xsl:attribute name="title"> 
      <xsl:value-of select="@componentTitle"/> 
     </xsl:attribute> 
     <xsl:attribute name="url"> 
      <xsl:value-of select="@pageURL"/> 
     </xsl:attribute> 
     </xsl:element> 
    </xsl:if> 
    </xsl:template> 
</xsl:stylesheet> 

Auparavant, il fonctionnait très bien, mais maintenant il y a un autre changement nécessaire, maintenant je dois les noeuds à rendre dont @title commence par « T » ou « t », ainsi que 3 suivant le caractère devrait être numéro par exemple dans ci-dessus xml "Calendrier de vol" ne devrait pas venir, je suppose que j'ai juste besoin d'écrire un de plus et de la condition en <xsl:if test="@componentTitle != ''">,

S'il vous plaît suggérer! comment ça peut être fait!

+0

Bonne question (1). Voir ma réponse pour une expression de doublure simplifiée et pour la façon standard de vérifier si une chaîne contient un nombre. :) –

+0

Bonne question (+1). Et voir mon meilleur one-liner. – dolmen

Répondre

-1

je suis venu avec une solution ci-dessous, s'il vous plaît indiquer si elle est OK!

<xsl:template match="tcm:Item"> 
    <xsl:if test="@componentTitle != '' and (starts-with(translate(@Title, 't', 'T'), 'T')and string(number(substring(@Title,2,3))) != 'NaN')"> 
     <xsl:element name="tab"> 
     <xsl:attribute name="id"> 
      <xsl:value-of select="substring-after(@ID, '-')"/> 
     </xsl:attribute> 
     <xsl:attribute name="title"> 
      <xsl:value-of select="@componentTitle"/> 
     </xsl:attribute> 
     <xsl:attribute name="url"> 
      <xsl:value-of select="@pageURL"/> 
     </xsl:attribute> 
     </xsl:element> 
    </xsl:if> 
    </xsl:template> 

Votre saisie est obligatoire!

+0

Au lieu de placer votre test dans le modèle, vous devez l'utiliser lors de la sélection des nœuds, dans un élément 'apply-template'. – Oded

+0

@Oded: Le meilleur style XSLT est 'pure push'. Ne sélectionnez pas, juste correspondre. Voir ma solution, et beaucoup d'autres réponses que j'ai données, pour des exemples de style push pur. –

+0

'T0.0' correspond. Voir ma réponse qui accepte seulement les chiffres. – dolmen

0

Travailler avec XSLT que très rarement, je suis venu avec la solution suivante:

<xsl:if test="@componentTitle != ''"> 
    <xsl:if test="starts-with(@Title,'T') or starts-with(@Title,'t')"> 
    <xsl:if test="string-length(@Title) &gt; 3"> 
     <xsl:if test="string(number(substring(@Title,2,3))) != 'NaN'"> 
... 
     </xsl:if> 
    </xsl:if> 
    </xsl:if> 
</xsl:if> 

J'ai remarqué que certaines fonctions, il a également lower-case/upper-case qui pourrait être utilisé pour tester le premier caractère étant un t ou T mais ils semblent être uniquement disponibles en XSLT2.0.

+0

Merci beaucoup André pour votre temps et votre solution, cependant pouvez-vous s'il vous plaît vérifier ci-dessous la solution proposée par moi-même! –

+0

Quatre "imbriqués" !!!! Certainement peut être refactorisé. –

1

Vous devez sélectionner les nœuds que vous voulez utiliser dans vos modèles dans l'élément apply-templates:

<xsl:apply-templates select="tcm:Item[@componentTitle != '' 
          and (starts-with(translate(@Title, 't', 'T'), 'T') 
          and string(number(substring(@Title,2,3))) != 'NaN')]"> 

J'ai utilisé le test @solution produit pour cela - il fonctionne bien pour l'exigence (testé here).

Cela vaut mieux que de sélectionner tous les nœuds tcm:Item et de les tester une à la fois dans le modèle.

+0

Encore mieux est le style pur "push" - ne sélectionnez pas, juste correspondre. –

+0

-1 parce que 'T0.0' correspond. – dolmen

1

La logique de sélection est mieux placée dans le modèle de correspondance du modèle - et elle peut aussi être un peu simplifiée.

<xsl:template match= 
"tcm:Item[contains('tT', substring(@Title,1,1)) 
     and 
      number(substring(@Title,2,3)) 
      =  
      number(substring(@Title,2,3)) 
      ] 
"> 

Une règle à retenir: Toujours tester si une chaîne $s représente un nombre - comme ceci:

number($s) = number($s)

+0

+1 pour le test de nombre et la suggestion de correspondance de motif. –

2

est ici l'expression la plus simple qui fera la mise en correspondance:

translate(substring(@Title, 1, 4), 't12345679', 'T000000000') = 'T000' 

Voici le modèle:

<xsl:template match=" 
tcm:Item[translate(substring(@Title, 1, 4), 't12345679', 'T000000000') = 'T000' 
and @componentTitle != '' "/> 
+0

+1 parce que c'est un modèle généralement utile. c'est-à-dire en utilisant translate pour créer une correspondance de chaîne qui implémente votre règle métier. Et concis sans être illisible. –

Questions connexes