2011-01-13 14 views
6

Tengo el siguiente nodo XSLT:¿Cómo puedo agregar varios filtros a un XSLT para cada instrucción?

<xsl:for-each select="Book[title != 'Moby Dick']"> 
.... 
</xsl:for-each> 

Sin embargo, me gustaría uso de varios filtros en la for-each. He intentado lo siguiente, pero no parece funcionar:

<!-- Attempt #1 --> 
<xsl:for-each select="Book[title != 'Moby Dick'] or Book[author != 'Rowling'] "> 
.... 
</xsl:for-each> 


<!-- Attempt #2 --> 
<xsl:for-each select="Book[title != 'Moby Dick' or author != 'Rowling']"> 
.... 
</xsl:for-each> 
+0

debe proporcionar muestra de XML. – Flack

+0

Buena pregunta, +1. Vea mi respuesta para una explicación y varias soluciones de una sola línea. :) –

Respuesta

19

Sin embargo, me gustaría uso de varios filtros en el for-each

Su pregunta real es un XPath uno: ¿Es posible, y cómo, para especificar más de una condición dentro de un predicado?

respuesta:

Sí, use los operadores booleanos estándar XPath or y and y la función XPath estándar not().

En este caso particular, el XPath en el atributo select puede ser:

Book[title != 'Moby Dick' or author != 'Rowling'] 

Yo personalmente siempre prefiero escribir una expresión equivalente:

Book[not(title = 'Moby Dick') or not(author = 'Rowling')] 

porque el operador != tiene un comportamiento no intuitivo cuando uno de sus operandos es un conjunto de nodos.

Pero estoy adivinando que lo que quería era probablemente a and los dos comparissons - no or ellos.

+0

+1 Respuesta completa y excelente. –

+0

Si tiene la oportunidad, ¿le importaría explicar o vincular a una explicación sobre el comportamiento no intuitivo del operador! =? ¡Gracias! –

+0

@Neil Whitaker: si al menos uno de los operandos del operador '! =' Es un conjunto de nodos (o un conjunto de nodos o una secuencia en XPath 2.0), entonces es posible que tanto '$ arg1 = $ arg2 'y' $ arg1! = $ arg2' son verdaderos al mismo tiempo. Simplemente lea la definición del operador '! ='. Esto se evita si usa 'not ($ arg1 = $ arg2)' –

0

Al parecer, se me olvidó para actualizar mis datos. El intento # 2 funciona perfectamente bien. Espero que este ejemplo ayude a alguien más.

<!-- Attempt #2 --> 
<xsl:for-each select="Book[title != 'Moby Dick' or author != 'Rowling']"> 
.... 
</xsl:for-each> 
+0

@Dimitre - si Rowling hubiera escrito un libro llamado Moby Dick, ¿el predicado seguramente sería falso para ese libro? –

+0

@Michael: Por supuesto que tienes razón. Probablemente estaba pensando que el elemento * same * estaba participando en dos comparaciones '! =' Con diferentes valores, cuyas comparaciones fueron luego editadas. Debe haber estado bastante cansado anoche ... De todos modos, eliminé una declaración similar de mi respuesta. Gracias. –

1

Si quiere múltiples predicados, la forma más simple es simplemente usar predicados múltiples. Supongo que realmente quiere una "y" en lugar de una "o":

<xsl:for-each select="Book[title != 'Moby Dick'][author != 'Rowling'] "> 
.... 
</xsl:for-each> 

En general, el = es mejor evitar operador, ya que tiene efectos inesperados cuando el autor está ausente o cuando hay varios autores . Es mejor escribir:

<xsl:for-each select="Book[not(title = 'Moby Dick')][not(author = 'Rowling')] "> 
.... 
</xsl:for-each> 
Cuestiones relacionadas