2010-09-05 19 views
5

Sto usando XSLT1.0 per trasformare il mio XML.Il controllo del carattere iniziale deve essere 'T' e il successivo 3 carattere deve essere il numero in xslt

Sto avendo seguito 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> 

e sto usando qui sotto XSLT per trasformarla!

<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> 

precedenza, è stato funzionando benissimo, ma ora c'è un altro cambiamento richiesto, ora devo quelle nodo da cui rendering @Title inizia con 'T' o 't' così come accanto 3 personaggio dovrebbe essere numero per esempio in sopra xml "Flight Schedule" non dovrebbe venire, presumo ho solo bisogno di scrivere un altro e condizione in <xsl:if test="@componentTitle != ''">,

Si prega di suggerire! come può essere fatto!

+0

Buona domanda (+1). Vedere la mia risposta per un'espressione semplificata con un solo liner e per il modo standard per verificare se una stringa contiene un numero. :) –

+0

Buona domanda (+1). E vedi il mio migliore one-liner. – dolmen

risposta

-1

Mi è venuta in mente una soluzione, suggerire se è 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> 

È necessario tutto l'input!

+0

Invece di inserire il test nel modello, dovresti usarlo quando selezioni i nodi, in un elemento 'apply-template'. – Oded

+0

@Oded: il miglior stile XSLT è 'pure push'. Non selezionare, basta abbinare. Vedi la mia soluzione e molte altre risposte che ho dato, per esempi di puro stile push. –

+0

"T0.0" corrisponde. Vedi la mia risposta che accetta solo cifre. – dolmen

0

Lavorare con XSLT solo occasionalmente, mi si avvicinò con la seguente soluzione:

<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> 

ho notato che ci sono funzioni anche lower-case/upper-case che potrebbe essere utilizzato per il test per il primo carattere di essere un t o T ma sembrano essere disponibili solo in XSLT2.0.

+0

Molte grazie Andre per il tuo tempo e la tua soluzione, tuttavia puoi controllare la soluzione qui sotto proposta me stesso! –

+0

Quattro nidificati 'if' s !!!! Certamente può essere refactored. –

1

Si dovrebbe selezionare i nodi che si desidera operare su nei modelli nell'elemento 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')]"> 

ho usato il test che @solution prodotto per questo - funziona bene per il requisito (testato here).

Questo è meglio che selezionare tutti i nodi tcm:Item e verificarli uno alla volta nel modello.

+0

Ancora meglio è il puro stile "push": non selezionare, basta abbinare. –

+0

-1 perché "T0.0" corrisponde. – dolmen

1

La logica di selezione viene inserita nel modello di corrispondenza del modello e può anche essere un po 'semplificata.

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

Una regola da ricordare: verificare sempre se qualche stringa $s rappresenta un numero - come questo:

number($s) = number($s)

+0

+1 per la verifica del numero e la ricerca della corrispondenza del modello. –

2

Qui è l'espressione più semplice che farà l'abbinamento:

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

Ecco il modello:

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

+1 perché questo è un modello generalmente utile. Ad esempio, utilizza translate per creare una corrispondenza stringa che implementa la regola aziendale. E conciso senza essere illeggibile. –

Problemi correlati