2010-08-09 14 views
5

mio file XML è la seguente:Incarica CSS all'elemento in un XSL

<worksheet> 
<row> 
<rowTitle>RT1</rowTitle> 
<rowType>yesorno</rowType> 
<subLine>subLine1Content</subLine> 
<subLine>subLine2Content</subLine> 
</row> 
<row> 
<rowTitle>RT2</rowTitle> 
<rowType>operation</rowType> 
<subLine>subLine1Content</subLine> 
<subLine>subLine2Content</subLine> 
<subLine>subLine3Content</subLine> 
</row> 
. 
. 
</worksheet> 

nel mio xsl, durante la visualizzazione di contenuti di una riga particolare, mi piacerebbe aggiungere una classe all'elemento HTML che specificherò il tipo di riga che è. Ho provato a usare xsl: scegliere e assegnare un valore a una variabile xsl: ma questo non funziona. Sto cercando di visualizzare la riga come

<ol> 
<li class="rowTypeBoolean"> 
RT1 
<ul><li>subLineContent1</li> 
<li>subLineContent2</li></ul> 
</li> 
<li class="rowTypeOptions"> 
RT2 
<ul><li>subLineContent1</li> 
<li>subLineContent2</li> 
<li>subLineContent3</li></ul> 
</li> 
.  
. 
</ol> 

file XSL frammento

<xsl:template match="row"> 
     <li class="rowClass ${className}"> 
      <xsl:choose> 
       <xsl:when test="type = 'YESORNO'"> 
        <xsl:variable name="className" select="rowTypeBoolean"/> 
       </xsl:when> 
       <xsl:when test="type = 'OPTIONS'"> 
        <xsl:variable name="className" select="rowTypeOptions"/> 
       </xsl:when> 
       <xsl:when test="type = 'OPERATION'"> 
        <xsl:variable name="className" select="rowTypeOperation"/> 
       </xsl:when> 
       <xsl:otherwise> 
        <xsl:variable name="className" select="rowTypeOther"/> 
       </xsl:otherwise> 
      </xsl:choose> 
      <span class="rowTitleClass"> 
       <xsl:value-of select="rowtitle"/> 
      </span> 
      <br/> 
      <ul class="subLineListClass"> 
       <xsl:apply-templates select="subLine"/> 
      </ul> 
     </li> 
</xsl:template> 
+0

Hai pubblicato il tuo XML e l'output desiderato. Puoi pubblicare l'XSL con cui hai attualmente problemi? – Oded

+0

Buona domanda (+1). Vedi la mia risposta per una soluzione completa che sia semplice ed eviti la codifica non necessaria della logica decisionale. –

risposta

9

È necessario aggiungerlo come attributo all'elemento:

<li> 
     <xsl:choose> 
      <xsl:when test="type = 'YESORNO'"> 
       <xsl:attribute name="className">rowTypeBoolean</xsl:attribute> 
      </xsl:when> 
      <xsl:when test="type = 'OPTIONS'"> 
       <xsl:attribute name="className">rowTypeOptions</xsl:attribute> 
      </xsl:when> 
      <xsl:when test="type = 'OPERATION'"> 
       <xsl:attribute name="className">rowTypeOperation"</xsl:attribute> 
      </xsl:when> 
      <xsl:otherwise> 
       <xsl:attribute name="className">rowTypeOther"</xsl:attribute> 
      </xsl:otherwise> 
     </xsl:choose> 
    </li> 
6

La soluzione più ingenuo sarebbe utilizzare l'istruzione xsl:choose in questo modo:

<li> 
    <xsl:attribute name="className"> 
     <xsl:choose> 
      <xsl:when test="type = 'YESORNO'">rowTypeBoolean</xsl:when> 
      <xsl:when test="type = 'OPTIONS'">rowTypeOptions</xsl:when> 
      <xsl:when test="type = 'OPERATION'">rowTypeOperation</xsl:when> 
      <xsl:otherwise>rowTypeOther</xsl:otherwise> 
     </xsl:choose> 
    </xsl:attribute> 
</li> 

Altro modo sarebbe avere una mappa in linea (o tramite fn:document()) come:

<li class="{$map[@type = current()/type]|$map[not(@type)]}"/> 

Con questo come elemento di livello superiore

<map:map xmlns:map="map"> 
    <item type="YESORNO">rowTypeBoolean</item> 
    <item type="OPTIONS">rowTypeOption</item> 
    <item type="OPERATIONS">rowTypeOperation</item> 
    <item>rowTypeOther</item> 
</map:map> 

<xsl:variable name="map" select="document('')/*/map:map/*" xmlns:map="map"/> 
+2

+1 da parte mia per un'ottima soluzione. –

4

Non è affatto necessario utilizzare <xsl:choose> nella trasformazione:

Questa trasformazione:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

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

<xsl:template match="worksheet"> 
    <ol> 
    <xsl:apply-templates/> 
    </ol> 
</xsl:template> 

<xsl:template match="row[rowType='yesorno']"> 
    <li class="rowTypeBoolean"> 
    <xsl:apply-templates/> 
    </li> 
</xsl:template> 

<xsl:template match="row[rowType='operation']"> 
    <li class="rowTypeOperation"> 
    <xsl:apply-templates/> 
    </li> 
</xsl:template> 

<xsl:template match="row[rowType='options']"> 
    <li class="rowTypeOptions"> 
    <xsl:apply-templates/> 
    </li> 
</xsl:template> 

<xsl:template match="row"> 
    <li class="rowTypeOther"> 
    <xsl:apply-templates/> 
    </li> 
</xsl:template> 

<xsl:template match="subLine[1]"> 
    <ul> 
    <xsl:apply-templates select="../subLine" mode="process"/> 
    </ul> 
</xsl:template> 

    <xsl:template match="subLine" mode="process"> 
    <li><xsl:apply-templates/></li> 
    </xsl:template> 

</xsl:stylesheet> 

se applicato sul documento XML fornito:

<worksheet> 
    <row> 
     <rowTitle>RT1</rowTitle> 
     <rowType>yesorno</rowType> 
     <subLine>subLine1Content</subLine> 
     <subLine>subLine2Content</subLine> 
    </row> 
    <row> 
     <rowTitle>RT2</rowTitle> 
     <rowType>operation</rowType> 
     <subLine>subLine1Content</subLine> 
     <subLine>subLine2Content</subLine> 
     <subLine>subLine3Content</subLine> 
    </row> 
</worksheet> 

produce il desiderato, risultato corretto:

<ol> 
    <li class="rowTypeBoolean"> 
     <rowTitle>RT1</rowTitle> 
     <rowType>yesorno</rowType> 
     <ul> 
      <li>subLine1Content</li> 
      <li>subLine2Content</li> 
     </ul> 
     <subLine>subLine2Content</subLine> 
    </li> 
    <li class="rowTypeOperation"> 
     <rowTitle>RT2</rowTitle> 
     <rowType>operation</rowType> 
     <ul> 
      <li>subLine1Content</li> 
      <li>subLine2Content</li> 
      <li>subLine3Content</li> 
     </ul> 
     <subLine>subLine2Content</subLine> 
     <subLine>subLine3Content</subLine> 
    </li> 
</ol> 

Do atto:

  1. Vengono utilizzati solo modelli semplici e <xsl:apply-templates>. Pertanto, le possibilità di commettere un errore sono ridotte al minimo.

  2. Questo codice è intrinsecamente estensibile e mantenibile. Se viene introdotto un nuovo tipo di riga, non sarà necessario modificare nessuno dei modelli esistenti: sarà sufficiente aggiungere un nuovo modello breve e semplice, che corrisponda a un elemento row che ha un figlio rowType con il nuovo valore.

  3. La mappatura tra rowType e il corrispondente valore dell'attributo class può essere specificato in un elemento namespace speciale livello globale e/o variabile (come fatto in soluzione di Alejandro), o anche in un documento XML separato. Quindi possiamo avere un solo modello, corrispondente a row.