2010-12-31 33 views
9

Tôi có một tình huống mà tôi nghĩ rằng tôi cần phải xích chuỗi chuyển đổi xslt của tôi (tức là đầu ra của một biến đổi xslt đang được nhập vào một biến khác). Biến đổi đầu tiên khá phức tạp với nhiều xsl: choice và xpaths tổ tiên. Suy nghĩ của tôi là biến xml thành xml mà sau đó có thể dễ dàng chuyển thành html.Có phải chuỗi xâu chuỗi xslt được chấp nhận không?

Câu hỏi của tôi là 'Thực tiễn chuẩn này hay tôi thiếu gì đó?'

Xin cảm ơn trước.

Stephen

+0

Câu hỏi hay, +1. Xem câu trả lời của tôi cho lời giải thích và một ví dụ mã hoàn chỉnh. :) –

+1

Có, nó được chấp nhận, nhưng không phải lúc nào cũng cần thiết. Nếu bạn đang sử dụng Java, Transformerfactory có thể được cấu hình để cằm biến đổi liên tiếp và tránh các hoạt động phân tích cú pháp không cần thiết. http://stackoverflow.com/questions/1312406/efficient-xslt-pipeline-in-java-or-redirecting-results-to-sources/1319774#1319774 –

Trả lời

0

tôi sẽ không nghĩ đó là chuẩn thực tế, đặc biệt là kể từ khi bạn có thể chuyển đổi một phương ngữ XML trực tiếp khác.

Tuy nhiên, nếu quá trình xử lý phức tạp, việc chia nhỏ thành nhiều bước (áp dụng một biến đổi khác nhau trong mỗi bước) thực sự có thể đơn giản hóa từng bước và có ý nghĩa.

Nó thực sự phụ thuộc vào tình huống cụ thể.

9

Thực hiện chuỗi chuyển đổi được sử dụng khá thường xuyên trong các ứng dụng XSLT, mặc dù thực hiện điều này hoàn toàn trong XSLT 1.0 yêu cầu sử dụng hàm xxx:node-set() của nhà cung cấp cụ thể. Trong XSLT 2.0 không cần mở rộng như vậy vì kiểu dữ liệu RTF khét tiếng được loại bỏ ở đó.

Dưới đây là một ví dụ (quá đơn giản để có ý nghĩa, nhưng minh họa hoàn toàn cách này được thực hiện):

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:ext="http://exslt.org/common"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:template match="/"> 
    <xsl:variable name="vrtfPass1"> 
    <xsl:apply-templates select="/*/*"/> 
    </xsl:variable> 

    <xsl:variable name="vPass1" 
     select="ext:node-set($vrtfPass1)"/> 

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

<xsl:template match="num[. mod 2 = 1]"> 
    <xsl:copy-of select="."/> 
</xsl:template> 

<xsl:template match="num" mode="pass2"> 
    <xsl:copy> 
    <xsl:value-of select=". *2"/> 
    </xsl:copy> 
</xsl:template> 
</xsl:stylesheet> 

khi chuyển đổi này được áp dụng trên các tài liệu XML sau:

<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> 

mong muốn, kết quả chính xác được tạo ra:

<num>2</num> 
<num>6</num> 
<num>10</num> 
<num>14</num> 
<num>18</num> 

Giải thích:

  1. Trong bước đầu tiên trên tài liệu XML được chuyển và kết quả được định nghĩa là giá trị của biến $vrtfPass1. Điều này chỉ sao chép các phần tử num có giá trị kỳ lạ (thậm chí không).

  2. Biến $vrtfPass1, là loại RTF, là không trực tiếp sử dụng cho XPath biểu thức vì vậy chúng tôi chuyển nó sang một cái cây bình thường, sử dụng EXSLT (thực hiện bởi hầu hết XSLT 1.0 vi xử lý) chức năng ext:node-set và xác định một biến khác - - $vPass1 có giá trị là cây này.

  3. Bây giờ chúng tôi thực hiện phép chuyển đổi thứ hai trong chuỗi biến đổi của chúng tôi - trên kết quả của phép biến đổi đầu tiên, được giữ như giá trị của biến $vPass1. Không gây rối với mẫu đầu tiên, chúng tôi chỉ định rằng quá trình xử lý mới phải ở chế độ có tên, được gọi là "pass2". Trong chế độ này, giá trị của bất kỳ phần tử num nào được nhân với hai.

XSLT 2.0 giải pháp (không RTFs):

<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:template match="/"> 
    <xsl:variable name="vPass1" > 
    <xsl:apply-templates select="/*/*"/> 
    </xsl:variable> 
    <xsl:apply-templates mode="pass2" 
     select="$vPass1/*"/> 
</xsl:template> 

<xsl:template match="num[. mod 2 = 1]"> 
    <xsl:copy-of select="."/> 
</xsl:template> 

<xsl:template match="num" mode="pass2"> 
    <xsl:copy> 
    <xsl:value-of select=". *2"/> 
    </xsl:copy> 
</xsl:template> 
</xsl:stylesheet> 
1

Nếu đây là tình hình của bạn (hoặc có thể trở thành tình bạn):

  1. Biến đổi xml ban đầu để xml mediary.
  2. Có thể chuyển xml trung gian thành final1_html.
  3. Có thể biến đổi xml trung gian thành final2_html (không giống như final1_html).

hoặc

  1. Biến đổi xml ban đầu vào xml mediary. Điều này là hợp lý có khả năng thay đổi theo thời gian.
  2. Chuyển xml trung gian thành final_html. Điều này không có khả năng thay đổi theo thời gian.

Sau đó, bạn nên sử dụng phép chuyển đổi hai bước.

Nếu đây là tình hình của bạn:

  1. Biến đổi xml ban đầu để xml mediary.
  2. Chuyển xml trung gian thành final_html.

Sau đó, xem xét không phải là hai bước. Thay vào đó, chỉ cần thực hiện một phép biến đổi.

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