2011-01-13 5 views
6

Tôi có nút XSLT sau:Tôi làm cách nào để thêm nhiều bộ lọc vào một câu lệnh XSLT cho mỗi câu lệnh?

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

Tuy nhiên, tôi muốn sử dụng nhiều bộ lọc trong for-each. Tôi đã thử những điều sau đây, nhưng dường như không hoạt động:

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

bạn nên cung cấp mẫu XML. – Flack

+0

Câu hỏi hay, +1. Xem câu trả lời của tôi để giải thích và một số giải pháp một lớp. :) –

Trả lời

19

Tuy nhiên, tôi muốn sử dụng nhiều bộ lọc trong for-each

câu hỏi thực sự của bạn là một XPath một: Có thể, và làm thế nào, để xác định nhiều hơn một điều kiện bên trong một vị từ?

trả lời:

Có, sử dụng các tiêu chuẩn XPath boolean khai thác orand và tiêu chuẩn chức năng XPath not().

Trong trường hợp đặc biệt này, XPath trong thuộc tính select có thể:

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

Cá nhân tôi sẽ luôn luôn thích để viết một biểu thức tương đương:

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

vì các nhà điều hành != có một hành vi không trực quan khi một trong các toán hạng của nó là một tập hợp nút.

Nhưng tôi đoán rằng những gì bạn có thể muốn là and hai so sánh - không phải or chúng.

+0

+1 Câu trả lời hoàn chỉnh và tuyệt vời. –

+0

Nếu bạn có cơ hội, bạn có thể giải thích hoặc liên kết với một lời giải thích về hành vi không trực quan của toán tử! = Không? Cảm ơn! –

+0

@Neil Whitaker: nếu ít nhất một toán hạng của toán tử '! =' Là một bộ nút (hoặc một bộ nút hoặc một chuỗi trong XPath 2.0), thì có thể cả hai '$ arg1 = $ arg2 'và' $ arg1! = $ arg2' là đúng cùng một lúc. Chỉ cần đọc định nghĩa của toán tử '! ='. Điều này tránh được nếu bạn sử dụng 'không ($ arg1 = $ arg2)' –

0

Rõ ràng, tôi quên làm mới dữ liệu của mình. Cố gắng # 2 hoạt động hoàn toàn tốt đẹp. Hy vọng ví dụ này giúp người khác.

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

@Dimitre - nếu Rowling đã viết một cuốn sách có tên Moby Dick, vị ngữ chắc chắn sẽ sai cho cuốn sách đó? –

+0

@Michael: Tất nhiên bạn đúng. Có lẽ tôi đã nghĩ rằng yếu tố * cùng * đã tham gia vào hai so sánh '! =' Với các giá trị khác nhau, mà so sánh sau đó là or-ed. Chắc hẳn đã khá mệt mỏi đêm qua ... Dù sao, tôi đã loại bỏ một tuyên bố tương tự từ câu trả lời của tôi. Cảm ơn bạn. –

1

Nếu bạn muốn nhiều vị từ, cách đơn giản nhất là chỉ sử dụng nhiều vị từ. Tôi đoán bạn thực sự muốn một "và" thay vì "hoặc":

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

Nói chung, toán tử! = Tốt nhất nên tránh vì nó có tác dụng bất ngờ khi tác giả vắng mặt hoặc khi có nhiều tác giả . Tốt hơn là viết:

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