2009-02-10 16 views
26

Diciamo che ho un doc XML come questo:Come fare riferimento al valore corrente del nodo in XSL per ogni test?

<books> 
    <book>1110</book> 
    <book>1111</book> 
    <book>1112</book> 
    <book>1113</book> 
</books> 

sto cercando di impostare una condizione che mette alla prova il valore del nodo corrente nel for-each, ma sto facendo qualcosa di sbagliato:

<xsl:for-each select="/books/book"> 
    <xsl:if test=".[='1112']"> 
     Success 
    </xsl:if> 
</xsl:for-each> 

Cosa sto facendo in modo errato?

+0

. [SomeBoolean] non è valida sintatticamente in XPath 1.0. –

risposta

37

L'utilizzo di . può, infatti, fare riferimento al nodo corrente (o "contesto"), ma non al modo in cui lo si utilizza qui. In XPath, .[foo] non è una sintassi valida: è necessario utilizzare self::node()[foo]. Inoltre, l'operatore = bisogno di qualcosa per abbinare contro, in questo caso il selettore text() per accedere ai contenuti il ​​testo dell'elemento:

<xsl:for-each select="/books/book"> 
    <xsl:if test="self::node()[text()='1112']"> 
     Success 
    </xsl:if> 
</xsl:for-each> 

Come indicato nelle altre risposte, tuttavia, a meno che il for-each sta eseguendo altre operazioni come pure, non è necessario per scorrere a tutti e può usare solo if per eseguire la stessa operazione:

<xsl:if test="/books/book[. = 1112]"> 
    Success 
</xsl:if> 
3

Mentre Ben ha risposto correttamente alla tua domanda, utilizzando per-ognuno è sicuramente l'approccio generale sbagliata. Dopo tutto questo è XSLT. Così si sono probabilmente più alla ricerca di qualcosa di simile:

<xsl:if test="/books/book[text()='1112']"> 
    Success 
</xsl:if> 
+0

Vero; Supponevo che l'OP stesse semplicemente eliminando la porzione rilevante di un blocco 'for-each' più grande, ma se questo è il suo insieme, sarebbe molto meglio usare questo semplice' if' invece. –

12

che sto cercando di impostare una condizione che verifica il valore del nodo corrente nel la for-each, ma sto facendo qualcosa sbagliato:

la prima cosa che non è corretto è la sintassi:

.[='1112'] 

Ci sono due cose sbagliate qui:

  1. Entro [e] non v'è alcun predicato: l'operatore "=" ha bisogno di due argomenti, ma solo uno è fornito.

  2. .[x = y] è ancora una sintassi non valida, sebbene il predicato sia OK. Ciò deve essere specificato come:

    self :: node() [condizione]

La seconda cosa nel codice fornito che può essere migliorato è l'istruzione <xsl:for-each>, che isn' assolutamente necessario; Una singola espressione XPath sarà sufficiente.

Riassumendo, una possibile espressione XPath che restituisce il valore booleano richiesta è:

/books/book[. = '1112'] 

Se è proprio necessario che la condizione da testare all'interno istruzione <xsl:for-each>, quindi una corretta XPath espressione che uso è:

. = '1112' 

Quanto sopra è una str Il confronto e lo potrebbero non essere validi per true() se ci sono spazi intorno. Pertanto, un confronto numerico può essere meglio:

. = 1112 
+1

L'espressione '. = '1112'' ha funzionato bene per me. Grazie. –

+0

@HosamAly, prego. –

1

prova con questo

<xsl:for-each select="/books/book"> 
    <xsl:if test="current() = '1112'"> 
     Success 
    </xsl:if> 
</xsl:for-each> 
Problemi correlati