2013-01-10 30 views
6

Tôi đang gặp sự cố nhỏ.Tham chiếu biến XSLT qua tên động

Các XSL-File:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:fn="http://www.w3.org/2005/xpath-functions"> 
<xsl:template match="/"> 


<xsl:variable name="unumericValue" select="10" /> 
<xsl:variable name="uanotherValue" select="8" /> 



<xsl:for-each select="/root/try"> 
<xsl:value-of select="var" /> 
<xsl:variable name="min"><xsl:value-of select="@minimum" /></xsl:variable> 
<xsl:value-of select="@type" /> 
<xsl:variable name="referenceName"><xsl:value-of select='concat("u",var)' /></xsl:variable> 
<xsl:value-of select="$referenceName" /> 
<xsl:if test='$referenceName > $min'> 
<p>Do something.</p> 
</xsl:if> 
</xsl:for-each> 

</xsl:template> 
</xsl:stylesheet> 

File XML:

<?xml version="1.0" encoding="UTF-8"?> 
<?xml-stylesheet type="text/xsl" href="q1.xsl"?> 
<root> 
<try type="compare" minimum="9"> 
<var>numericValue</var> 
<something>...</something> 
</try> 

<try type="compare" minimum="10"> 
<var>anotherValue</var> 
<something>...</something> 
</try> 
</root> 

Như bạn có thể thấy các tập tin XML có hai var-Elements mà phải phù hợp với các biến trong XSLT-File . Tuy nhiên tôi không biết Cú pháp nào là chính xác. $ referenceName chỉ là tên của biến mà tôi muốn sử dụng. Nhưng tôi không biết làm thế nào để tham chiếu tên đến biến hiện tại.

Trả lời

11

$referenceName không phải là tham chiếu đến biến có tên "unumericValue" hoặc cách khác. Nó chỉ là giá trị chuỗi "unumericValue", v.v. Vì vậy, nó sẽ không bao giờ lớn hơn $min. Tuy nhiên, với một chút công việc khác, có một mẹo để tìm biến theo tên của nó:

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

    <xsl:variable name="numericValue" select="10" /> 
    <xsl:variable name="anotherValue" select="8" /> 
    <xsl:variable name="vars" select="document('')/*/xsl:variable" /> 

    <xsl:template match="/"> 
    <xsl:variable name="referenceName" select="'numericValue'" /> 
    <xsl:variable name="referenceValue" select="$vars[@name = $referenceName]/@select" /> 
    Reference value: <xsl:value-of select="$referenceValue" /> 
    </xsl:template> 
</xsl:stylesheet> 

Một hạn chế lớn cần lưu ý ở đây là chỉ làm việc cho các biến là giá trị số không đổi.

Đây là một cách để mô phỏng các biến với các giá trị chuỗi liên tục:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       xmlns:v="variables-node" 
> 
    <v:variables> 
    <v:variable n="numericValue" value="10" /> 
    <v:variable n="nonNumericValue" value="Hello World" /> 
    </v:variables> 
    <xsl:variable name="vars" select="document('')//v:variables/v:variable" /> 

    <xsl:template match="/"> 
     <xsl:variable name="referenceName" select="'nonNumericValue'" /> 
     <xsl:variable name="referenceValue" select="$vars[@n = $referenceName]/@value" /> 
     <xsl:value-of select="concat('The variable with the name ', $referenceName, ' has the value ', $referenceValue)"/> 
    </xsl:template> 
</xsl:stylesheet> 

Và cuối cùng, một cách để mô phỏng các biến với các giá trị tính toán:

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

    <xsl:variable name="varsRaw"> 
    <var n="computedValue" value="{concat('2 + 4 is ', 2 + 4)}" /> 
    <var n="computedNumber" value="{22 div 7}" /> 
    </xsl:variable> 
    <xsl:variable name="vars" select="exslt:node-set($varsRaw)/var" /> 

    <xsl:template match="/"> 
     <xsl:variable name="referenceName" select="'computedValue'" /> 
     <xsl:variable name="referenceValue" select="$vars[@n = $referenceName]/@value" /> 
     <xsl:value-of select="concat('The variable with the name ', $referenceName, ' has the value ', $referenceValue)"/> 

     <xsl:value-of select="'  '"/> 

     <xsl:variable name="referenceName2" select="'computedNumber'" /> 
     <xsl:variable name="referenceValue2" select="$vars[@n = $referenceName2]/@value" /> 
     <xsl:value-of select="concat('The variable with the name ', $referenceName2, ' has the value ', $referenceValue2)"/> 
    </xsl:template> 
</xsl:stylesheet> 

Phương pháp cuối cùng có lẽ là thực sự là chính thống nhất , nhưng yêu cầu chức năng phụ thuộc vào bộ xử lý XSLT (ít nhất là trong XSLT 1.0) node-set().

+0

Cảm ơn rất nhiều. Đề nghị đầu tiên làm việc tuyệt vời cho tôi. – eadrax

1

Giống như hầu hết các ngôn ngữ lập trình, các tên biến XSLT không thể truy cập được trong thời gian chạy. Biến có thể thậm chí không tồn tại trong thời gian chạy - trình tối ưu hóa được phép chơi tất cả các loại thủ thuật, như nội tuyến tất cả các tham chiếu đến biến tại điểm mà biến được sử dụng.

Cách tiếp cận tốt nhất là có biến với tên chuẩn và cung cấp nội dung XML. Các tên phần tử và thuộc tính trong XML có thể truy cập tại thời gian chạy, không giống như các tên biến.

5

Bằng cách này, không làm điều này:

<xsl:variable name="min"><xsl:value-of select="@minimum" /></xsl:variable> 

khi bạn có thể làm điều này:

<xsl:variable name="min" select="@minimum" /> 

Nó không chỉ tiết, nó cũng không hiệu quả - không cần phải sao chép dữ liệu và xây dựng một cây mới, đó là một hoạt động rất tốn kém, khi tất cả các bạn muốn là một tham chiếu đến một nút hiện có.

+0

Tất nhiên bạn đã đúng. Nó cũng dễ dàng hơn và ngắn hơn để viết :) – eadrax

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