2012-01-31 36 views
6

Tôi muốn sử dụng các thuộc tính @sourcename theo cách sau, như là một tiện nghi:XSLT: gán biến bằng một trong hai trường hợp

Nếu @sourcename có một dấu chấm trong đó, phần trước dấu chấm đầu tiên nên được chỉ định đến $srcgroup và một phần sau dấu chấm đầu tiên sẽ được gán cho $srcword.

Nếu không $srcgroup phải được đặt bằng @sourcename$srcword phải là chuỗi rỗng.

Trong cả hai trường hợp, tôi muốn thực hiện những việc tương tự bằng cách sử dụng $srcgroup$srcword.

tôi đã cố gắng điều này với các đoạn sau:

<xsl:choose> 
    <xsl:when test="contains(@sourcename, '.')">  
    <xsl:variable name="srcgroup" select="substring-before(@sourcename, '.')"/> 
    <xsl:variable name="srcword" select="substring-after(@sourcename, '.')" /> 
    </xsl:when> 
    <xsl:otherwise> 
    <xsl:variable name="srcgroup" select="@sourcename" /> 
    <xsl:variable name="srcword" />      
    </xsl:otherwise> 
</xsl:choose> 

<foo group="{$srcgroup}" word="{$srcword}" /> 
<!-- there's some other more complicated users of $srcgroup and $srcword --> 

Vấn đề là tôi nhận được một lỗi (điều này được sử dụng JAXP trong Java):

ERROR: [my xsl file]: line 35: Variable or parameter 'srcgroup' is undefined.' 
FATAL ERROR: 'Could not compile stylesheet' 
Exception in thread "main" javax.xml.transform.TransformerConfigurationException: Could not compile stylesheet 
    at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl.newTemplates(TransformerFactoryImpl.java:825) 

Nếu tôi hiểu đúng này, tôi m đoán các biến chỉ có phạm vi của trường hợp cụ thể trong khối <xsl:choose>. Có cách nào để làm được việc này? Tôi không muốn lặp lại mã khác hai lần.


p.s. Tôi đã tìm thấy giải pháp thay thế:

<xsl:variable name="srcgroup" select="substring-before(concat(@sourcename, '.'), '.')" /> 
<xsl:variable name="srcword" select="substring-after(@sourcename, '.')" /> 

nhưng tôi vẫn muốn biết cách giải quyết câu hỏi ban đầu của mình, để tham khảo trong tương lai.

Trả lời

5

Chỉ cần sử dụng (không điều kiện cần thiết):

<xsl:variable name="srcgroup" select= 
    "substring-before(concat(@sourcename, '.'), '.')"/> 

    <xsl:variable name="srcword" select= 
    "substring-after(@sourcename, '.')"/> 

Hoàn dụ:

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

<xsl:template match="x|y"> 
    <xsl:variable name="srcgroup" select= 
    "substring-before(concat(@sourcename, '.'), '.')"/> 

    <xsl:variable name="srcword" select= 
    "substring-after(@sourcename, '.')"/> 

    $srcgroup = "<xsl:value-of select="$srcgroup"/>" 
    $srcword = "<xsl:value-of select="$srcword"/>" 
</xsl:template> 
</xsl:stylesheet> 

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

<t> 
    <x sourcename="a.b.c"/> 
    <y sourcename="noDots"/> 
</t> 

kết quả mong muốn được sản xuất trong cả hai trường hợp:

$srcgroup = "a" 
    $srcword = "b.c" 

    $srcgroup = "noDots" 
    $srcword = "" 

Giải thích: logic không cần thiết tránh được bằng cách đặt một sentinel.


Hãy so sánh này cho nhiều hơn nữa tiết có điều kiện Cú pháp:

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

<xsl:template match="x|y"> 
    <xsl:variable name="srcgroup"> 
    <xsl:choose> 
    <xsl:when test="contains(@sourcename, '.')"> 
     <xsl:value-of select="substring-before(@sourcename, '.')"/> 
    </xsl:when> 
    <xsl:otherwise> 
     <xsl:value-of select="@sourcename"/> 
    </xsl:otherwise> 
    </xsl:choose> 
    </xsl:variable> 

    <xsl:variable name="srcword"> 
    <xsl:choose> 
    <xsl:when test="contains(@sourcename, '.')"> 
     <xsl:value-of select="substring-after(@sourcename, '.')"/> 
    </xsl:when> 
    <xsl:otherwise/> 
    </xsl:choose> 
    </xsl:variable> 

    $srcgroup = "<xsl:value-of select="$srcgroup"/>" 
    $srcword = "<xsl:value-of select="$srcword"/>" 
</xsl:template> 
</xsl:stylesheet> 

Khi chuyển đổi tiết hơn này được áp dụng trên cùng một tài liệu XML (ở trên), một lần nữa kết quả chính xác cùng được sản xuất:

$srcgroup = "a" 
    $srcword = "b.c" 

    $srcgroup = "noDots" 
    $srcword = "" 
+0

Nếu bạn đọc nhận xét của tôi ở cuối bài đăng của tôi, bạn sẽ thấy rằng tôi đã tìm ra điều này rất hữu ích trong việc xử lý trường hợp cụ thể đó, nhưng nó không trả lời câu hỏi của tôi về cách gán một biến. –

+0

Nhân tiện, bạn có lỗi - bạn không nên sử dụng concat trong trường hợp 'chuỗi con sau 'vì nó tạo dấu chấm ở cuối' srcword' trong trường hợp không trống. –

+0

@ Jason: Tôi đã sửa câu trả lời của mình. Và có, nó chính xác trả lời câu hỏi làm thế nào để có điều kiện xác định một biến. Như bạn thấy, không có điều kiện là cần thiết để xác định các biến theo cách mong muốn. –

5

Đó là nhiều hơn như thế này:

<xsl:variable name="srcgroup"> 
<xsl:choose...> 
    ... 
</xsl:choose> 
</xsl:variable> 
+0

+1, nhưng bạn có thể giúp tôi với cú pháp không? Tôi không quen với cách sử dụng '' mà không có 'select =' –

+0

Nội dung của thẻ là giá trị của biến. Đặt '' vào đó bạn đặt gán vào ''. –

+0

Và xem tại đây - http://www.w3.org/TR/xslt - bất cứ khi nào nghi ngờ, tài nguyên thực sự hữu ích. –

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