2010-05-14 45 views
7

Tôi chắc chắn rằng đây là một câu hỏi cực kỳ cơ bản nhưng ở đây vẫn xảy ra! Tôi đã đọc rằng việc xây dựng trong mẫu quy tắc cho văn bản và thuộc tính nút trong XSLT làQuy tắc mẫu được xây dựng trong XSLT cho các thuộc tính

<xsl:template match="text()|@*"> 
    <xsl:value-of select="."/> 
</xsl:template> 

Tuy nhiên đối với các tài liệu nguồn

<?xml version="1.0"?> 
<booker> 
<award> 
    <author blah="test">Aravind Adiga</author> 
    <title>The White Tiger</title> 
    <year>2008</year> 
</award> 
</booker> 

Và XSLT

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

tôi nhận được kết quả như sau áp dụng biến đổi trong Visual Studio. Ai đó có thể vui lòng giải thích tại sao tôi không thấy "kiểm tra" trong đầu ra?

Aravind Adiga

The White Tiger

Trả lời

6

Bởi vì được xây dựng trong quy tắc cho các yếu tố không áp dụng các mẫu để các thuộc tính riêng của một nguyên tố, chỉ để nó là phần tử con. Nếu bạn muốn đi qua các thuộc tính trong cùng một cách mà bạn đi qua các yếu tố con (mà có lẽ là một nhiệm vụ nhân tạo), bạn cần phải xác định mặc định của riêng bạn:

<xsl:template match="*"> 
    <xsl:apply-templates select="@*"/> 
    <xsl:apply-templates/> 
</xsl:template> 
+1

Tôi đồng ý, chỉ cần thêm để hoàn thành - mặc định '' chọn tất cả các nút con, không chỉ các phần tử (nếu không, sẽ không có kết quả đầu ra của mã từ câu hỏi). – Krab

+0

Cảm ơn, tôi không cần phải thực sự làm điều đó, tôi chỉ đang cố hiểu các quy tắc. Vì vậy, về cơ bản phần '@ *' của quy tắc dựng sẵn sẽ không bao giờ được gọi trừ khi nó được gọi một cách rõ ràng? –

6

Để giải quyết câu hỏi này từ một bình luận:

Cảm ơn, tôi không cần phải thực sự làm điều đó, tôi chỉ đang cố hiểu các quy tắc. Vì vậy, về cơ bản phần @ * của quy tắc dựng sẵn sẽ không bao giờ được gọi trừ khi nó được gọi một cách rõ ràng?

Trong trường hợp này, có hai quy tắc mặc định mà chúng tôi quan tâm:

<xsl:template match="text()|@*"> 
    <xsl:value-of select="."/> 
</xsl:template> 

<xsl:template match="/|*"> 
    <xsl:apply-templates/> 
</xsl:template> 

Khi tài liệu được xử lý, mẫu thứ hai phù hợp với gốc và áp dụng-mẫu. Mặc định cho các ứng dụng-templates là chọn tất cả các nút con (các thuộc tính, gây nhầm lẫn, không phải là các nút con). Bạn không bao giờ chọn bất kỳ thuộc tính nào để được xử lý vì chỉ apply-templates xuất hiện ở dạng mặc định.

Vì vậy, nếu bạn chọn một nơi nào đó bất kỳ thuộc tính nào (như Vincent Marchetti đã làm), nó sẽ được xử lý bằng mẫu mặc định được đề cập đầu tiên.

+0

+1 Tôi hiểu rồi! Cảm ơn tất cả bây giờ có ý nghĩa. –

2

Quy tắc chính là - các thuộc tính không có danh tính chút nào - chúng chỉ có thể truy cập được dưới dạng các bit nằm ngang được gắn với nút. Thật tốt khi nghĩ về chúng như là không tồn tại cho đến khi bạn có một nút đầu tiên. Bạn cũng có thể nghĩ họ là những công dân hạng hai hoàn toàn trong thế giới XPath và XSLT. Mỗi khi bạn sử dụng chúng trong các điều kiện lựa chọn, nó giống như bạn đã chuyển từ một phép nối sang một con trỏ trong SQL và mỗi khi bạn sử dụng "for" thay vì "apply" thì điều tương tự cũng xảy ra.

Một cách khác để đặt nó - chỉ mục "hiệu quả" thực sự mà bạn có là chỉ số có tất cả XPath trong tài liệu (.Net thực sự xây dựng Hashtable của XPaths => so khớp thời gian không đổi). Lý do "áp dụng" được đặc quyền là nó đảm bảo xử lý chức năng thuần túy - bạn có thể chạy mọi thứ phù hợp bằng cách áp dụng trên các luồng riêng biệt không có đồng bộ hóa và không chia sẻ bộ nhớ - bạn chỉ cần concat kết quả của chúng.Cách thứ ba để xem xét, đó là một căng, hãy tưởng tượng rằng thẻ của bạn là các bảng SQL và bạn chỉ thay thế PK-s và FK-s - không có gì khác bạn thực sự có thể chọn ngoại trừ "tất cả từ T1 và tất cả liên quan đến họ từ T2 ". Đối với bất kỳ động cơ SQL phong nha nó giống như một nỗ lực 0-chi phí để làm điều đó - nó chỉ đọc một mục chỉ mục tốt bởi mục kể từ khi cấu trúc rất của nó là 1-1 với truy vấn của bạn. Mọi thứ khác chi phí nhiều hơn nữa.

Khi bạn đã chọn thẻ và mẫu phù hợp và đang chạy, thì sẽ rẻ để chỉ lấy giá trị của thuộc tính - miễn là bạn chỉ cần chuyển đổi/hiển thị chúng. Các bài kiểm tra Attrib ở cuối XPath khá rẻ - một lần nữa kể từ khi thẻ/nút cuối cùng được chọn và bây giờ nó chỉ là một bộ lọc nhỏ trên đầu trang của nó.

Vì vậy, công cụ XSLT và lựa chọn XPath nói chung có lý do rất tốt để bỏ qua hoàn toàn các thuộc tính - perf.

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