2010-01-26 35 views
5

Tôi có đúng khi nghĩ rằng tuyên bố apply-templates phải khớp với tất cả các mẫu có thể được áp dụng cho lựa chọn không?Hiểu về `áp dụng mẫu 'khớp với

Ví dụ, do đoạn xml sau:

<doc> 
    <foo bar="1" baz="2">boz</foo> 
</doc> 

và stylesheet sau:

<xsl:template match="/"> 
    <xsl:apply-templates select="foo" mode="xyz" /> 
</xsl:template> 

<xsl:template mode="xyz" match="foo[bar='1']"> 
    abc 
</xsl:template> 

<xsl:template mode="xyz" match="foo[baz='2']"> 
    def 
</xsl:template> 

Tôi mong chờ đầu ra là:

abc 
def 

là đúng này ?

Trả lời

6

Không, bạn không nhận được cả hai kết quả đầu ra, như chỉ có một mẫu sẽ được chọn. Xem this page để biết các quy tắc về giải quyết xung đột nếu có nhiều mẫu có thể.

Sau khi sửa biểu định kiểu của bạn (tương tự như cách Rubens đã làm, nhưng với cùng chế độ), điều này thường sẽ dẫn đến mẫu cuối cùng trong tệp xslt của bạn được áp dụng, vì vậy đầu ra sẽ là def. Điều này là do hai mẫu có cùng mức độ ưu tiên và nếu bộ xử lý xslt của bạn không dừng lại với lỗi, tiêu chuẩn yêu cầu áp dụng mã cuối cùng:

Đó là lỗi nếu điều này bỏ nhiều quy tắc mẫu phù hợp . Một bộ xử lý XSLT có thể báo hiệu lỗi; nếu nó không báo hiệu lỗi, nó phải khôi phục bằng cách chọn, từ trong số các quy tắc mẫu phù hợp còn lại, quy tắc xuất hiện cuối cùng trong biểu định kiểu.

+0

+1, câu trả lời hay nhất –

0

Nếu bạn khắc phục điều đó mã XSLT (bạn có một số vấn đề lọc) và chạy nó, bạn sẽ thấy:

def

Tại sao? <xsl:apply-templates /> sẽ khớp với mẫu đầu tiên đáp ứng điều kiện đối sánh của bạn. Nếu bạn có hai mẫu, bạn nên để khác biệt hơn bằng cách sử dụng mà <xsl:apply-templates>mode thuộc tính, hoặc bằng cách sử dụng <xsl:template>priority thuộc tính:

<xsl:stylesheet version="1.0" 
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:template match="/doc"> 
     <xsl:apply-templates select="foo" mode="2" /> 
    </xsl:template> 

    <xsl:template mode="1" match="foo[@bar='1']"> 
     abc 
    </xsl:template> 

    <xsl:template mode="2" match="foo[@baz='2']"> 
     def 
    </xsl:template> 

</xsl:stylesheet> 
4

Nếu bạn đã muốn mẫu của bạn để phù hợp cho cả các thuộc tính, sau đó bạn sẽ chỉ cần phải điều chỉnh match XPath để chọn thuộc tính và đặt mối quan hệ với foo ở vị; thay vì có hai mẫu xung đột phù hợp trên yếu tố foo có cùng độ đặc hiệu (có cùng mức độ ưu tiên).

<?xml version="1.0" encoding="UTF-8"?> 
    <xsl:stylesheet 
    version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes" encoding="UTF-8"/> 

<xsl:template match="/"> 
    <xsl:apply-templates select="doc/foo" /> 
</xsl:template> 

<!--When templates match on foo, apply templates for it's attributes --> 
<xsl:template match="foo"> 
    <xsl:apply-templates select="@*"/> 
</xsl:template> 

<!--Unique template match for the bar attribute --> 
<xsl:template match="@bar[parent::foo and .='1']"> 
    abc 
</xsl:template> 

<!--Unique template match for the baz attribute --> 
<xsl:template match="@baz[parent::foo and .='2']"> 
    def 
</xsl:template> 

</xsl:stylesheet> 
+0

Cảm ơn, đây là những gì tôi muốn làm. Thật không may tôi không thể chấp nhận câu trả lời vì nó không đi vào "lý do". ;) –

Các vấn đề liên quan