2010-06-25 42 views
6

Tôi muốn tệp đầu ra được tạo của mình chứa đường dẫn tệp trỏ đến đường dẫn tương ứng với biểu định kiểu. Vị trí của biểu định kiểu có thể thay đổi và tôi không muốn sử dụng thông số cho biểu định kiểu. Giải pháp của tôi cho việc này là nhận được biểu định kiểu đầy đủ URI:Thực hiện thao tác trên đường dẫn tệp trong XSLT

<xsl:variable name="stylesheetURI" select="document-uri(document(''))" /> 

Bây giờ tôi chỉ cần cắt tên tệp từ $stylesheetURI. Điều này đã truyền cảm hứng cho tôi viết XSLT 2.0 nhái của các chức năng PHP basenamedirname:

<xsl:function name="de:basename"> 
    <xsl:param name="file"></xsl:param> 
    <xsl:sequence select="tokenize($file, '/')[last()]" /> 
</xsl:function> 

<xsl:function name="de:dirname"> 
    <xsl:param name="file"></xsl:param> 
    <xsl:sequence 
     select="string-join(tokenize($file, '/')[position() != last()], '/')" /> 
</xsl:function> 

Bây giờ tôi có thể làm một cái gì đó như thế này trong mẫu của tôi:

<img src="{concat(de:dirname($stylesheetURI),'/img/myimage,png')}" /> 

Câu hỏi của tôi là: Có tốt hơn/cách nhanh hơn để thực hiện điều này với XSLT 2.0 gốc?

+0

Tôi thích làm việc với câu hỏi này (+1). Xem câu trả lời của tôi cho những gì dường như nhanh hơn 25%. :) –

Trả lời

7

Tôi đã thử nghiệm (không quá rộng) các chức năng này và chúng dường như thực hiện nhanh hơn 25% so với được cung cấp. Tất nhiên, kết quả phụ thuộc vào độ dài chuỗi và số lượng vòng loại:

<xsl:function name="de:basename" as="xs:string"> 
    <xsl:param name="pfile" as="xs:string"/> 
    <xsl:sequence select= 
    "de:reverseStr(substring-before(de:reverseStr($pfile), '/')) 
    " /> 
    </xsl:function> 

    <xsl:function name="de:dirname" as="xs:string"> 
    <xsl:param name="pfile" as="xs:string"/> 
    <xsl:sequence select= 
    "de:reverseStr(substring-after(de:reverseStr($pfile), '/')) 
    " /> 
    </xsl:function> 

    <xsl:function name="de:reverseStr" as="xs:string"> 
    <xsl:param name="pStr" as="xs:string"/> 

    <xsl:sequence select= 
    "codepoints-to-string(reverse(string-to-codepoints($pStr)))"/> 
    </xsl:function> 
+0

Thật tuyệt vời! Nó có thể được điều này bởi vì thực hiện trình tự (với tokenize và chuỗi tham gia) có chi phí porform hơn chuỗi thao tác? Nhưng, không chuỗi-to-codeponits cũng trả về một chuỗi? –

+0

@Alejandro: tokenize() thực hiện rất nhiều công việc - quét char bằng char và đặt mọi mã thông báo trong một mục riêng biệt. Bất cứ nơi nào chuỗi con trước() hoặc chuỗi con sau() chỉ quét lên lần xuất hiện đầu tiên. –

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