2010-07-07 33 views
8

Tôi có một số phép biến đổi XSLT 2.0 phức tạp. Tôi đang cố gắng tìm hiểu xem có cách nào có mục đích chung để đảm bảo rằng không có thẻ trống nào được xuất ra. Vì vậy, ... về mặt khái niệm, một giai đoạn xử lý cuối cùng sẽ loại bỏ đệ quy tất cả các thẻ trống. Tôi hiểu điều này có thể được thực hiện bởi một XSLT riêng biệt mà không làm gì ngoài việc lọc ra các thẻ rỗng, nhưng tôi cần phải có tất cả các gói được đóng gói cùng nhau trong một thẻ duy nhất.Xử lý hai pha: Không xuất các thẻ trống từ quá trình xử lý XSLT 2.0 giai đoạn 1

+0

xuất sắc câu hỏi (1). Xem câu trả lời của tôi cho một giải pháp chi tiết. –

Trả lời

8

XSLT này 2.0 chuyển đổi minh họa cách đa-pass (trong trường hợp này 2-pass) xử lý có thể được thực hiện:

<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 
    <xsl:strip-space elements="*"/> 

<xsl:template match="node()|@*" mode="#all"> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*" mode="#current"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="/"> 
    <xsl:variable name="vPass1"> 
    <xsl:apply-templates/> 
    </xsl:variable> 

    <xsl:apply-templates select="$vPass1/*" mode="non-empty"/> 
</xsl:template> 

<xsl:template match="text()[xs:integer(.) mod 2 eq 0]"/> 

<xsl:template match="*[not(node())]" mode="non-empty"/> 
</xsl:stylesheet> 

khi áp dụng trên tài liệu XML này:

<nums> 
    <num>01</num> 
    <num>02</num> 
    <num>03</num> 
    <num>04</num> 
    <num>05</num> 
    <num>06</num> 
    <num>07</num> 
    <num>08</num> 
    <num>09</num> 
    <num>10</num> 
</nums> 

Nó tạo ra một tài liệu kết quả trong lần vượt qua đầu tiên (được ghi lại trong biến số $vPass1), trong đó tất cả các phần tử <num> có nội dung thậm chí là intege r bị tước bỏ nội dung của họ và trống rỗng. Sau đó, trong lần truyền thứ hai, được áp dụng trong một chế độ cụ thể, tất cả các phần tử trống sẽ bị xóa.

Kết quả của việc chuyển đổi là:

<nums> 
    <num>01</num> 
    <num>03</num> 
    <num>05</num> 
    <num>07</num> 
    <num>09</num> 
</nums> 

Do lưu ý việc sử dụng các chế độ, và các phương thức đặc biệt #all#current.

Cập nhật: OP bây giờ muốn trong nhận xét để xóa "đệ quy" "tất cả các nút không có hậu duệ không trống".

Điều này có thể được triển khai đơn giản hơn bằng cách sử dụng không đệ quy rõ ràng. Chỉ cần thay đổi:

<xsl:template match="*[not(node())]" mode="non-empty"/> 

tới:

<xsl:template match="*[not(descendant::text())]" mode="non-empty"/> 
+0

Điều này trả lời câu hỏi tổng thể, nhưng có một phần cụ thể nó bỏ qua - đệ quy xóa tất cả các thẻ trống ... vì vậy tôi chỉ cần thay đổi "* [not (node ​​())]" thành một biểu thức thích hợp có nghĩa là tất cả các nút không có hậu duệ không trống. – mentics

+0

@taotree Thời gian tới nêu rõ câu hỏi của bạn tốt hơn. :) Tôi nghĩ rằng tốt nhất là làm cho yêu cầu mới này là một câu hỏi riêng biệt - nó cũng sẽ là một câu hỏi tuyệt vời. Bạn có thể sử dụng cho mẫu đối sánh của mẫu trống này: '* [not (descendant :: text())]' –

+0

@taotree Cập nhật câu trả lời để phản ánh yêu cầu mới của bạn ... :) –

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