2014-09-02 82 views
0

我必須使用XSLT 2.0將xml數據轉換爲固定長度的文本文件。xslt自定義函數用空格填充字符串值

我可以使用類似<xsl:value-of select="substring(concat(../../msg:StreamStart/msg:Stream/msg:AgencyBankParameter, ' '), 1, 10)"/>這樣的工作,但有20列,所有這些輸出到不同的長度我認爲使用全局函數來連接字符串和返回子字符串會更優雅。

所以我寫了這一點:

<xsl:function name="func:padStr"> 
    <xsl:param name="str"/> 
    <xsl:param name="chr"/> 
    <xsl:param name="len"/> 
    <xsl:value-of select="substring(concat($str,$chr),1,$len)"/> 
</xsl:function> 

這下XSLT 2.0精細編譯,但是當我嘗試使用它在我的XSL失敗。

我已經嘗試了本墊上面的字符串值,但它不能每次都和我不知道下一步該怎麼嘗試:

這裏是我完整的XML:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:msg="http://www.voca.com/schemas/messaging" 
xmlns:cmn="http://www.voca.com/schemas/common" > 
<xsl:output method="text" encoding="UTF-8" /> 

<xsl:function name="func:padStr"> 
    <xsl:param name="str"/> 
    <xsl:param name="chr"/> 
    <xsl:param name="len"/> 
    <xsl:value-of select="substring(concat($str,$chr),1,$len)"/> 
</xsl:function> 

<xsl:template match="/"> 
    <xsl:for-each select="msg:VocaDocument/msg:Data/msg:Document/msg:DDIVouchers/msg:Voucher"> 
     <xsl:value-of select="substring(concat(../../msg:StreamStart/msg:Stream/msg:AgencyBankParameter, '   '), 1, 10)"/> 

     <!-- THIS CAUSES A FAIL -->  
     <xsl:value-of select="func:padStr('../../msg:StreamStart/msg:Stream/msg:AgencyBankParameter', ' '), 1, 10)"/> 

     <xsl:value-of select="../../msg:StreamStart/msg:Stream/msg:AgencyBankParameter" /> 
     <xsl:value-of select="../../msg:StreamStart/msg:Stream/msg:BankName" /> 
     <xsl:value-of select="../../msg:StreamStart/msg:Stream/msg:BankCode" /> 
     <xsl:value-of select="../../msg:StreamStart/msg:Stream/msg:AgencyBankName" /> 
     <xsl:value-of select="../../msg:StreamStart/msg:Stream/msg:AgencyBankCode" /> 
     <xsl:value-of select="../../msg:StreamStart/msg:Stream/msg:StreamCode" /> 
     <xsl:value-of select="../../msg:StreamStart/msg:Stream/msg:VoucherSortCode" /> 
     <xsl:value-of select="../../msg:StreamStart/msg:Stream/msg:VoucherAccountNumber" /> 
     <xsl:value-of select="msg:BankAccount/msg:SortCode" /> 
     <xsl:value-of select="msg:BankAccount/msg:AccountNumber" /> 
     <xsl:value-of select="msg:BankAccount/msg:TotalVouchers" /> 

     <!-- NOTE HOW TO EXTRACT AN ADDRESS ELEMENT THAT HAS ITS OWN NAMESPACE --> 
     <xsl:value-of select="msg:ContactDetails/msg:Address/cmn:AddresseeName" /> 
     <xsl:value-of select="msg:ContactDetails/msg:Address/cmn:PostalName" /> 
     <xsl:value-of select="msg:ContactDetails/msg:Address/cmn:AddressLine" /> 
     <xsl:value-of select="msg:ContactDetails/msg:Address/cmn:TownName" /> 
     <xsl:value-of select="msg:ContactDetails/msg:Address/cmn:CountyIdentification" /> 
     <xsl:value-of select="msg:ContactDetails/msg:Address/cmn:CountryName" /> 
     <xsl:value-of select="msg:ContactDetails/msg:Address/cmn:ZipCode" /> 

     <xsl:text>&#xD;&#xA;</xsl:text> 
    </xsl:for-each> 
</xsl:template> 

</xsl:stylesheet> 

這裏(爲完整性)是我的xml:

<VocaDocument xmlns:cmn="http://www.voca.com/schemas/common" xmlns="http://www.voca.com/schemas/messaging" xmlns:iso="http://www.voca.com/schemas/common/iso" xmlns:env="http://www.voca.com/schemas/envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.voca.com/schemas/messaging http://www.voca.com/schemas/messaging/Voca_AUDDIS_AdviceofDDI_v1.0.xsd"> 
    <Data> 
     <Document> 
      <StreamStart> 
       <Stream> 
      <AgencyBankParameter>234</AgencyBankParameter> 
      <BankName>LLOYDS BANK PLC</BankName> 
      <BankCode>0004</BankCode> 
      <AgencyBankName>BANK OF CYPRUS UK LTD</AgencyBankName> 
      <AgencyBankCode>0234</AgencyBankCode> 
      <StreamCode>01</StreamCode> 
      <VoucherSortCode>SC300037</VoucherSortCode> 
      <VoucherAccountNumber>46990760</VoucherAccountNumber>    
      </Stream> 
      </StreamStart> 
      <DDIVouchers> 
       <Voucher> 
        <TransactionCode>NEW</TransactionCode> 
        <OriginatorIdentification> 
         <ServiceUserNumber>123456</ServiceUserNumber> 
        </OriginatorIdentification> 
       </Voucher>    
       <Voucher> 
        <TransactionCode>OLD</TransactionCode> 
        <OriginatorIdentification> 
         <ServiceUserNumber>789012</ServiceUserNumber> 
        </OriginatorIdentification> 
        <ContactDetails> 
      <PhoneNumber>020 83395862</PhoneNumber> 
      <FaxNumber> FAX</FaxNumber> 
       <Address> 
        <cmn:AddresseeName>RANALD LESLIE</cmn:AddresseeName> 
        <cmn:PostalName>NUFFIELD HEALTH </cmn:PostalName> 
        <cmn:AddressLine>NUFFIELD HOUSE</cmn:AddressLine> 
        <cmn:TownName>SURBITON</cmn:TownName> 
        <cmn:CountyIdentification> </cmn:CountyIdentification> 
        <cmn:CountryName>UNITED KINGDOM</cmn:CountryName> 
        <cmn:ZipCode>KT6 4BN</cmn:ZipCode> 
        </Address> 
     </ContactDetails> 
      <ProcessingDate>2014-08-19</ProcessingDate> 
      <BankAccount><FirstLastVoucherCode>FirstLast</FirstLastVoucherCode><AgencyBankCode>0234</AgencyBankCode><SortCode>SC300037</SortCode><AccountNumber>46990760</AccountNumber><TotalVouchers>1</TotalVouchers></BankAccount> 
       </Voucher> 


      </DDIVouchers> 
     </Document> 
    </Data> 
</VocaDocument> 

所以我應該如何編寫和調用該函數來填充每個列?

回答

1

你說這條線會導致失敗......

<xsl:value-of select="func:padStr('../../msg:StreamStart/msg:Stream/msg:AgencyBankParameter', ' '), 1, 10)"/> 

有三個理由爲什麼..

  1. 您還沒有聲明的名稱空間func任何地方
  2. 您傳入xpath表達式作爲第一個參數的文字字符串,而不僅僅是表達式本身
  3. 您的括號是不匹配的! 1個括號,2日收盤....

它可能應該是這樣的:

<xsl:value-of select="func:padStr(../../msg:StreamStart/msg:Stream/msg:AgencyBankParameter, '   ', 10)"/> 

(假設你聲明func命名空間太...

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:msg="http://www.voca.com/schemas/messaging" 
    xmlns:cmn="http://www.voca.com/schemas/common" 
    xmlns:func="myfunc"> 

當然,不得不傳遞10個字符的字符串,不太方便,所以最好還是可以定義這樣的函數...

<xsl:function name="func:padStr"> 
    <xsl:param name="str"/> 
    <xsl:param name="chr"/> 
    <xsl:param name="len"/> 
    <xsl:variable name="pad"> 
     <xsl:for-each select="1 to $len"> 
      <xsl:value-of select="$chr" /> 
     </xsl:for-each> 
    </xsl:variable> 
    <xsl:value-of select="substring(concat($str,$pad),1,$len)"/> 
</xsl:function> 

然後,你可以只是一個單一的填充字符

<xsl:value-of select="func:padStr(../../msg:StreamStart/msg:Stream/msg:AgencyBankParameter, ' ', 10)"/> 
+0

感謝調用它,但我得到一個錯誤'「命名空間‘MYFUNC’不包含任何功能。 Line:47 Char:2 Code:0 URI:http://www.w3schools.com/xsl/tryxslt_result.asp「' – 2014-09-02 19:01:52

+1

不要使用w3schools!那只是XSLT 1.0,請用http:// xsltransform嘗試。 net/instead。它更可愛 – 2014-09-02 19:03:55

+1

MSXML6只支持XSLT 1.0,如果你想使用XSLT 1.0,你必須將函數轉換爲一個named-template。 – 2014-09-02 19:24:20