2012-09-06 27 views
12

Tôi muốn áp dụng mẫu có chế độ phụ thuộc vào giá trị biến.Sử dụng giá trị của một biến trong chế độ áp dụng-mẫu

<xsl:variable name="mode" select="@attribute"/> 
<xsl:apply-templates mode="{$mode}"/> 

Tôi gặp lỗi khi không thể biên soạn biểu định kiểu. Giá trị của chế độ phải là một QName, nhưng nó là "{$ mode}".

Có khả năng sử dụng các chế độ phụ thuộc vào biến không?

+0

Những gì bạn muốn làm là cú pháp bất hợp pháp, nhưng nó là * có thể * trong XSLT 1.0 để đạt được hiệu quả tương tự, sử dụng nguyên tắc "tham chiếu mẫu" là nền tảng cho thư viện FXSL. –

+0

Cảm ơn bạn vì ý tưởng này! Tôi đã cố gắng để hiểu nó, nhưng tôi mới ở XSLT và không có nhiều kinh nghiệm với lập trình chức năng. Đối với các trường hợp được mô tả, nó là "over-thiết kế". Có lẽ, tôi có thể sử dụng nó một vài lần, khi tôi có nhiều kinh nghiệm hơn với nó. – maria90

+0

maria90, Đủ để biết rằng kỹ thuật đó tồn tại - sau đó sử dụng nó bất cứ khi nào cần thiết. –

Trả lời

7

Các lựa chọn duy nhất bạn phải sử dụng một chế độ nhất định dựa trên một biểu thức là sử dụng

<xsl:choose> 
    <xsl:when test="@attribute = 'foo'"> 
     <xsl:apply-templates mode="bar"/> 
    </xsl:when> 
    <xsl:otherwise> 
     <xsl:apply-templates/> 
    </xsl:otherwise> 
</xsl:choose> 

hoặc tương tự với một xsl:if. Giá trị thuộc tính mode thuộc tính cần phải tương ứng là QName trong XSLT 1.0 trong XSLT 2.0 cho phép QName hoặc mã thông báo đặc biệt như #current hoặc #default '. Nhưng bạn không thể tính toán giá trị mode vào thời gian chạy.

+0

Đây là ý tưởng đầu tiên của tôi để giải quyết vấn đề. Tôi muốn tránh kiểm tra các giá trị cụ thể của biến. Tuy nhiên, tôi sẽ sử dụng cách này bởi vì FXSL là một chút nặng nề đối với tôi. – maria90

3

chế độ không phải là ứng cử viên hợp lệ cho Mẫu giá trị thuộc tính (AVT). Bạn chỉ đơn giản là không thể làm điều này.

Từ XSLT 2.0 spec:

[Định nghĩa: Trong một thuộc tính được chỉ định là một giá trị thuộc tính mẫu, chẳng hạn như một thuộc tính của một yếu tố kết quả theo nghĩa đen, một biểu có thể được sử dụng bởi xung quanh khái niệm với các dấu ngoặc nhọn ({})].

chế độ không được chỉ định là AVT trong thông số kỹ thuật, vì vậy bạn không thể thực hiện điều này.

0

Tôi gặp lỗi khi không thể biên soạn biểu định kiểu. Giá trị của chế độ phải là QName, nhưng đó là "{$ mode}".

Có khả năng sử dụng các chế độ phụ thuộc vào biến không?

Không, điều này không được hỗ trợ trong bất kỳ phiên bản XSLT nào - 1.0, 2.0 hoặc 3.0.

Khi bạn đang cố gắng thi đua hàm bậc cao hơn (HOF), bạn có thể sử dụng nguyên tắc cơ bản của FXSL để thực hiện điều này trong XSLT 1.0.

FXSL 1.x là thư viện các mẫu được viết bằng XSLT 1.0 thuần túy hỗ trợ/mô phỏng HOF.

Đây là một giải pháp hoàn chỉnh dựa trên những nguyên tắc:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:f="http://fxsl.sf.net" exclude-result-prefixes="f"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

    <f:inc/> 
    <f:double/> 

<xsl:variable name="vModeInc" select="document('')/*/f:inc[1]"/> 
<xsl:variable name="vModeDouble" select="document('')/*/f:double[1]"/> 

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

<xsl:template match="/*"> 
    <nums> 
    <xsl:apply-templates select="$vModeInc"> 
     <xsl:with-param name="pNodes" select="node()"/> 
    </xsl:apply-templates> 
    </nums> 
============== 
    <nums> 
    <xsl:apply-templates select="$vModeDouble"> 
     <xsl:with-param name="pNodes" select="node()"/> 
    </xsl:apply-templates> 
    </nums> 
</xsl:template> 

<xsl:template match="f:inc"> 
    <xsl:param name="pNodes"/> 
    <xsl:apply-templates select="$pNodes" mode="incr"/> 
</xsl:template> 

<xsl:template match="f:double"> 
    <xsl:param name="pNodes"/> 
    <xsl:apply-templates select="$pNodes" mode="double"/> 
</xsl:template> 

<xsl:template match="num" mode="incr"> 
    <num><xsl:value-of select=".+1"/></num> 
</xsl:template> 

<xsl:template match="num" mode="double"> 
    <num><xsl:value-of select=".*2"/></num> 
</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> 

các truy nã, kết quả đúng là được sản xuất - các phần tử nums/num được xử lý trong một (mỗi) của hai chế độ có sẵn, de cấp phát trên biến quy định - $vModeInc (1 thêm vào mỗi giá trị) hoặc $vModeDouble (mỗi giá trị được nhân hai):

<nums> 
    <num>2</num> 
    <num>3</num> 
    <num>4</num> 
    <num>5</num> 
    <num>6</num> 
    <num>7</num> 
    <num>8</num> 
    <num>9</num> 
    <num>10</num> 
    <num>11</num> 
</nums> 
============== 
    <nums> 
    <num>2</num> 
    <num>4</num> 
    <num>6</num> 
    <num>8</num> 
    <num>10</num> 
    <num>12</num> 
    <num>14</num> 
    <num>16</num> 
    <num>18</num> 
    <num>20</num> 
</nums> 
+0

+1 Đó là thông minh. Tôi đã không theo kịp FXSL, nhưng tôi ước tôi có thời gian để làm như vậy. :-) Đối với bất kỳ ai khác đang đọc, bạn nên dành thời gian để theo dõi qua XSLT ở trên và xem nó đang làm gì. – LarsH

+0

@LarsH, Cảm ơn, chỉ cần đọc các ngôn ngữ đánh dấu cực đoan trên FXSL 2 - nó không mất quá nhiều thời gian. :) –

+0

bạn có thể cung cấp liên kết tới bài báo đó không? Tôi googled và tìm thấy điều này: http://fxsl.sourceforge.net/ trong đó có một liên kết đến 2 giấy tờ, cả hai đều bị hỏng. Ồ, phải không? http://conferences.idealliance.org/extreme/html/2006/Novatchev01/EML2006Novatchev01.html – LarsH

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