xslt自定义函数用空格填充字符串值

时间:2014-09-02 17:15:59

标签: xml xslt xslt-2.0 fixed-width

我必须使用XSLT 2.0将xml数据转换为固定长度的文本文件。

我可以使用类似<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 个答案:

答案 0 :(得分:1)

你说这行导致失败......

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

有三个原因......

  1. 您尚未在任何地方声明名称空间func
  2. 您将xpath表达式作为第一个参数的文字字符串传递,而不仅仅是表达式本身
  3. 你的括号错了! 1个开口支架,2个关闭....
  4. 这应该看起来像这样:

    <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)"/>