2009-09-13 47 views
5

Có thể tách thẻ ở các giới hạn chữ hoa và chữ thường, ví dụ: , thẻ 'UserLicenseCode' phải được chuyển thành 'Mã giấy phép người dùng' để các tiêu đề cột trông đẹp hơn một chút.Phân tách XSLT phức tạp?

Tôi đã làm điều gì đó như thế này trong quá khứ bằng cách sử dụng cụm từ thông dụng của Perl, nhưng XSLT là một trò chơi bóng hoàn toàn mới dành cho tôi.

Bất kỳ con trỏ nào trong việc tạo mẫu như vậy sẽ được đánh giá rất nhiều!

Cảm ơn Krishna

+1

+1, vì XSLT vẫn là một bí ẩn đối với tôi, vì vậy trong khi tôi không thể * trợ giúp *, tôi chắc chắn đang xem những phát triển ở đây. –

+0

+1 cho suy nghĩ phức tạp trong khi thực tế, nó chỉ là rất nhiều mã. :-) Không có gì là phức tạp khi bạn biết làm thế nào. –

Trả lời

2

Sử dụng đệ quy, chúng ta có thể đi bộ qua một chuỗi trong XSLT để đánh giá tất cả các nhân vật. Để thực hiện việc này, hãy tạo mẫu mới chỉ chấp nhận một tham số chuỗi. Kiểm tra ký tự đầu tiên và nếu đó là ký tự viết hoa, hãy viết dấu cách. Sau đó viết nhân vật. Sau đó, gọi lại mẫu với các ký tự còn lại bên trong một chuỗi. Điều này sẽ dẫn đến những gì bạn muốn làm.

Đó sẽ là con trỏ của bạn. Tôi sẽ cần một chút thời gian để tìm ra mẫu. :-)


Phải mất một số thử nghiệm, đặc biệt là để có được không gian bên trong toàn bộ điều. (Tôi bị lạm dụng một nhân vật cho điều này!) Tuy nhiên, mã này sẽ cung cấp cho bạn một ý tưởng ...

tôi đã sử dụng XML này:

<?xml version="1.0" encoding="UTF-8"?> 
<blah>UserLicenseCode</blah> 

và sau đó kiểu này:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format"> 
    <xsl:output method="text"/> 
    <xsl:variable name="Space">*</xsl:variable> 
    <xsl:template match="blah"> 
    <xsl:variable name="Split"> 
     <xsl:call-template name="Split"> 
      <xsl:with-param name="Value" select="."/> 
      <xsl:with-param name="First" select="true()"/> 
     </xsl:call-template></xsl:variable> 
     <xsl:value-of select="translate($Split, '*', ' ')" /> 
    </xsl:template> 
    <xsl:template name="Split"> 
     <xsl:param name="Value"/> 
     <xsl:param name="First" select="false()"/> 
     <xsl:if test="$Value!=''"> 
      <xsl:variable name="FirstChar" select="substring($Value, 1, 1)"/> 
      <xsl:variable name="Rest" select="substring-after($Value, $FirstChar)"/> 
       <xsl:if test="not($First)"> 
        <xsl:if test="translate($FirstChar, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', '..........................')= '.'"> 
         <xsl:value-of select="$Space"/> 
        </xsl:if> 
       </xsl:if> 
       <xsl:value-of select="$FirstChar"/> 
       <xsl:call-template name="Split"> 
        <xsl:with-param name="Value" select="$Rest"/> 
       </xsl:call-template> 
     </xsl:if> 
    </xsl:template> 
</xsl:stylesheet> 

và tôi nhận được kết quả là:

User License Code 

Hãy nhớ rằng không gian và các ký tự trắng khác có xu hướng bị tước đi om XML, đó là lý do tại sao tôi sử dụng một '*' thay vào đó, mà tôi dịch sang một không gian.

Tất nhiên, mã này có thể được cải thiện. Đó là những gì tôi có thể đưa ra trong 10 phút làm việc. Trong các ngôn ngữ khác, nó sẽ có ít dòng mã hơn nhưng trong XSLT nó vẫn còn khá nhanh, xem xét số lượng các dòng mã mà nó chứa.

+0

Cảm ơn! Làm việc như một say mê. Tôi không thấy bài đăng này trước khi đăng giải pháp của mình. Điều này xử lý các điều kiện biên tốt hơn. Cảm ơn bạn đã phản hồi nhanh! –

1

Một XSLT + giải pháp FXSL (trong XSLT 2.0, nhưng hầu như cùng một mã sẽ làm việc với XSLT 1.0 và FXSL 1.x:

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:f="http://fxsl.sf.net/" 
xmlns:testmap="testmap" 
exclude-result-prefixes="f testmap" 
> 
    <xsl:import href="../f/func-str-dvc-map.xsl"/> 
    <testmap:testmap/> 

    <xsl:output omit-xml-declaration="yes" indent="yes"/> 

    <xsl:template match="/"> 
    <xsl:variable name="vTestMap" select="document('')/*/testmap:*[1]"/> 

    '<xsl:value-of select="f:str-map($vTestMap, 'UserLicenseCode')" 
     />' 
    </xsl:template> 

    <xsl:template name="mySplit" match="*[namespace-uri() = 'testmap']" 
    mode="f:FXSL"> 
     <xsl:param name="arg1"/> 

     <xsl:value-of select= 
     "if(lower-case($arg1) ne $arg1) 
     then concat(' ', $arg1) 
     else $arg1 
     "/> 
    </xsl:template> 
</xsl:stylesheet> 

Khi việc chuyển đổi trên được áp dụng trên bất kỳ nguồn tài liệu XML (không sử dụng), kết quả đúng dự kiến ​​được sản xuất:

'User License Code'

do lưu ý:

  1. Chúng tôi đang sử dụng phiên bản DVC của hàm FXSL/mẫu str-map(). Đây là hàm bậc cao (HOF) có hai đối số: một hàm khác và một chuỗi. str-map() áp dụng hàm trên mọi ký tự của chuỗi và trả về kết nối của các kết quả.

  2. Vì hàm lower case() được sử dụng (trong phiên bản XSLT 2.0), chúng tôi không bị ràng buộc chỉ với bảng chữ cái Latinh.

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