2013-04-07 21 views
8

Tôi nghĩ rằng tôi đã thấy một sai lầm trong câu trả lời cho this question và chỉ ra. Tôi đã nói rằng tôi đã sai, và câu trả lời của tôi sau đó đã bị xóa.Kết hợp các phần tử con trong XSL

Tôi vẫn không thấy mình đã sai. Vì vậy, tôi đăng bài ở đây và hy vọng ai đó có thể giải thích sự hiểu lầm của tôi với tôi.

Câu trả lời tôi đã trả lời để giải thích việc sử dụng các mẫu áp dụng. Nó chứa XML và XSL sau, mô tả cách các mẫu sẽ được xuất hiện:

<!-- sample XML snippet --> 
<xml> 
    <foo /><bar /><baz /> 
</xml> 

<!-- sample XSLT snippet --> 
<xsl:template match="xml"> 
    <xsl:apply-templates select="*" /> <!-- three nodes selected here --> 
</xsl:template> 

<xsl:template match="foo"> <!-- will be called once --> 
    <xsl:text>foo element encountered</xsl:text> 
</xsl:template> 

<xsl:template match="xml/*"> <!-- will be called twice --> 
    <xsl:text>other element countered</xsl:text> 
</xsl:template> 

bình luận của tôi là mẫu cuối cùng trong nên là:

<xsl:template match="*"> <!-- will be called twice --> 
    <xsl:text>other element countered</xsl:text> 
</xsl:template> 

vì nút hiện tại đã là <xml>

Tôi được thông báo:

Không, xml/* là mẫu phù hợp với phần tử con của một phần tử có tên xml.

Kiểm tra câu trả lời gốc

Tuy nhiên, với XML này:

<xml> 
    <foo /><bar /><baz /> 
</xml> 

Và XSL stylesheet này (điền đoạn mã ở trên):

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

<xsl:template match="xml"> 
    <xsl:apply-templates select="*" /> <!-- three nodes selected here --> 
</xsl:template> 

<xsl:template match="foo"> <!-- will be called once --> 
    <xsl:text>foo element encountered.&#xa;</xsl:text> 
</xsl:template> 

<xsl:template match="xml/*"> <!-- will be called twice --> 
    <xsl:text>other element countered.&#xa;</xsl:text> 
</xsl:template> 

</xsl:stylesheet> 

tôi nhận được :

other element countered. 
other element countered. 
other element countered. 

Kiểm tra của tôi phiên bản 'chỉnh'

Nếu tôi thay thế các mẫu mới nhất với:

<xsl:template match="*"> <!-- will be called twice --> 
    <xsl:text>other element countered.&#xa;</xsl:text> 
</xsl:template> 

như mỗi câu trả lời của tôi, tôi nhận được:

foo element encountered. 
other element countered. 
other element countered. 

đó sẽ xuất hiện để đúng.

Tôi hy vọng câu hỏi của mình không vi phạm bất kỳ nguyên tắc nào, nhưng tôi không thể thấy rằng tôi sai và hy vọng ai đó có thể giải thích đầy đủ hơn.

PS. Tôi sợ câu trả lời ban đầu của tôi về câu hỏi khác đã được đăng dưới dạng câu trả lời, không phải là nhận xét vì tôi chưa có đủ điểm để đăng nhận xét. Tôi không chắc điều gì là tốt nhất để làm ...

+1

Cảm ơn vì đã tìm ra lỗi lầm ngu ngốc của tôi, nó đã được sửa ngay trong chủ đề khác. Điều này đã không được chú ý bởi tất cả mọi người khác, những người đã nhìn vào câu trả lời trong suốt những năm qua. – Tomalak

Trả lời

6

Điều này là đúng, theo số rules on the default priority of templates. Mẫu phù hợp với foo có mức độ ưu tiên mặc định là 0, một đối sánh * có mức ưu tiên mặc định là -0,5, nhưng một đối sánh xml/* có mức độ ưu tiên mặc định là 0.5. Mẫu xml/* được xem là cụ thể hơn so với mẫu foo, do đó, nó sẽ thắng khi có thể khớp.

Vì vậy, bạn đã đúng mà biểu hiện phù hợp của mẫu cần thiết để được * hơn xml/*, nhưng không phải vì lý do đúng - một xml/* mẫu thể phù hợp cho một apply-templates select="*" khi nút hiện tại là xml, và nó sẽ áp dụng cho bất kỳ yếu tố nào được chọn (vì chúng là tất cả trẻ em của xml) trừ khi có một mẫu khác có độ rõ ràng là priority lớn hơn 0,5 có thể được ưu tiên.

4

Tôi là người đã nói bạn không chính xác trong chủ đề khác, và sau khi xem xét vấn đề kỹ hơn, tôi có thể thấy rằng bạn đã đúng khi chỉ ra rằng Tomalak đã phạm sai lầm, nhưng không phải vì lý do bạn đưa ra (nếu tôi hiểu chính xác bình luận của bạn). match="xml/*"hiện các nút con phù hợp với phần tử <xml>, cho dù ngữ cảnh hiện tại có phải là nút <xml> khi được gọi là apply-templates hay không. Trong biểu thức match="", "nút hiện tại" là nút mà các mẫu đang được áp dụng, không phải là ngữ cảnh trong đó apply-templates được gọi, do đó, trong mẫu này, nút hiện tại sẽ là foo, barbaz. Bạn có thể quan sát từ thử nghiệm của riêng bạn ở trên rằng xml/* thực hiện thành công trong việc khớp các phần tử con của xml, nhưng trên thực tế, chúng phù hợp với họ hơn Tomalak nói rằng nó sẽ.

Sự cố với match="xml/*"quá cụ thể và có tác dụng ngược lại của những gì tôi nghĩ Tomalak dự định. Dường như anh ta có ý định này là một trò bắt tất cả cho trẻ em của xml không phù hợp với nhau, nhưng như Ian Roberts giải thích, mẫu này sẽ nâng cao mức ưu tiên cao hơn và bắt tất cả trẻ em nút xml.

Tôi biết nó đang bực bội ngay bây giờ không thể viết bình luận của riêng bạn, nhưng bạn sẽ sớm đủ. Và có thể tạo câu hỏi mới của riêng bạn để đặt câu hỏi về một chuỗi khác. Bạn không nên tạo câu trả lời để nhận xét về các câu trả lời khác.

+0

+1 Vâng, điều này thật đáng xấu hổ. :) – Tomalak