2010-09-09 33 views
5

Tất cả,Áp dụng Biến đổi XSLT cho một XML đã được chuyển đổi

Tôi có một tệp XML mà tôi chuyển đổi nó bằng cách sử dụng tài liệu XSLT sang một XML khác.

Tôi có thể xác định một bộ chuyển đổi khác trong cùng một tệp XSLT được áp dụng trong kết quả XML của phép biến đổi đầu tiên không?

Cảm ơn,

MK

+0

Bạn có muốn hai phép biến đổi xảy ra trong một lần truyền không? Và nếu như vậy, tại sao không cắt ra người đàn ông trung gian và chỉ cần chuyển đổi trực tiếp đến đầu ra dự định của bạn? – recursive

+0

Tại sao bạn cần điều này xảy ra với một XSLT đơn lẻ? Tại sao không có hai tệp riêng biệt? –

+0

Tôi có một ứng dụng chỉ chấp nhận một tệp XSLT nhưng tôi muốn áp dụng phép biến đổi thứ hai cho tệp mới được chuyển đổi. – koumides

Trả lời

9

Yes.

I. XSLT này 1.0 chuyển đổi:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:ext="http://exslt.org/common" 
xmlns:msxsl="urn:schemas-microsoft-com:xslt" 
> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:variable name="vrtfPass1"> 
    <xsl:apply-templates/> 
</xsl:variable> 

<xsl:template match="node()|@*" name="identity"> 
    <xsl:copy> 
    <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

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

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

<xsl:template match="num/text()" mode="pass2"> 
    <xsl:value-of select="1+."/> 
</xsl:template> 

<xsl:template match="/"> 
    <xsl:apply-templates select="ext:node-set($vrtfPass1)/*" mode="pass2"/> 
</xsl:template> 
</xsl:stylesheet> 

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

<t> 
<num>1</num> 
<num>2</num> 
<num>3</num> 
<num>4</num> 
<num>5</num> 
</t> 

sản xuất:

<t> 
    <num>3</num> 
    <num>5</num> 
    <num>7</num> 
    <num>9</num> 
    <num>11</num> 
</t> 

Do lưu ý:

  1. Hai biến đổi đang thực sự thực hiện, thứ hai được thực hiện trên kết quả của sự đầu tiên.

  2. Kết quả của phép biến đổi đầu tiên là nội dung của biến số $vrtfPass1.

  3. Trong XSLT 1.0, loại biến chứa cây XML được tạo động (tạm thời) (tài liệu XML hoặc đoạn XML) là RTF (Kết quả-Cây-phân đoạn). Không thể thực hiện các hoạt động XPath trên RTF - nó cần được chuyển đổi thành một bộ nút thông thường bằng cách sử dụng hàm mở rộng xxx:node-set(), được cung cấp bởi đại đa số các nhà cung cấp bộ xử lý XSLT 1.0. Trong ví dụ này exslt: node-set() được sử dụng, bởi vì EXSLT được thực hiện bởi nhiều nhà cung cấp khác nhau.

  4. Phép chuyển đổi thứ hai được áp dụng trên kết quả của: <xsl:apply-templates select="ext:node-set($vrtfPass1)/*" mode="pass2"/> đầu tiên. Một số mode riêng được sử dụng để tách riêng mã của hai phép biến đổi.

  5. Biến đổi đầu tiên nhân mỗi num/text() với 2. Biến đổi thứ hai tăng mỗi num/text(). Kết quả là 2*.+1

II. 2.0 Sự biến đổi này XSLT:

<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:variable name="vPass1"> 
    <xsl:apply-templates mode="pass1"/> 
</xsl:variable> 

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

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

<xsl:template match="num/text()" mode="pass1"> 
    <xsl:value-of select="2*xs:integer(.)"/> 
</xsl:template> 

<xsl:template match="num/text()" mode="pass2"> 
    <xsl:value-of select="1+."/> 
</xsl:template> 

<xsl:template match="/"> 
    <xsl:apply-templates select="$vPass1" mode="pass2"/> 
</xsl:template> 
</xsl:stylesheet> 

khi áp dụng trên tài liệu XML tương tự, sản xuất các truy nã và chính xác cùng một kết quả.

Lưu ý: Trong XSLT 2.0/XPath 2.0 loại RTF đã bị bãi bỏ. Không cần xxx:node-set() chức năng mở rộng.

+0

+1 Câu trả lời hay. Điều này cho thấy lý do tại sao RTF là một thiết kế xấu từ WG ... Ngoài ra, chúng ta không phải chỉ ra cách sử dụng 'fn: function-available' khi sử dụng các hàm mở rộng? –

+0

@Alejandro: Có thể sử dụng 'fn: function-available' sẽ hữu ích để xác định một trong nhiều phần mở rộng' xxx: node-set() 'mà bộ xử lý XSLT thực hiện - nhưng điều này thường được biết. –

+0

Tuyệt vời. Cảm ơn Dimitre rất nhiều. – koumides

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