2014-09-02 34 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