如何在xslt中添加空格并将记录限制为300个字符

时间:2018-12-16 18:28:23

标签: xml csv xslt

我写了一个xslt将xml转换为CSV。本质上,xslt将记录创建为三百个字符,并在没有数据的情况下添加空格直到记录达到300个限制。下面是xslt,它可以满足我的目的。但是我不得不使用一个有300个空格的变量Spaces来记录使用。

我的问题是,我很想知道是否有比我采用的方法更简单的方法。下面是我的xslt,您可以在其中看到变量空间。请让我知道我是否可以使用任何较短的变量代替。

<xsl:output method="text"/>
<xsl:variable name="delimiter" select="'&#x20;'"/>
<xsl:variable name="linefeed" select="'&#xD;&#xA;'"/>
<xsl:variable name="spaces" select="'&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;
    &#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;
    &#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;
    &#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;
    &#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;
    &#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;
    &#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;
    &#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;
    &#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;
    &#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;
    &#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;
    &#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;
    &#x20;&#x20;&#x20;&#x20;&#x20;&#x20;'"/>


<xsl:template match="wd:Report_Entry/wd:Payments_group">
    <xsl:variable name="Paymentamount" select="number(translate(wd:Payment_Total_Amount,'.',''))"/>
    <xsl:variable name="Var_CheckNumber" select="format-number(wd:Check_Number, '0000000000')"/>
    <xsl:variable name="Var_Payment" select="format-number($Paymentamount, '0000000000')"/>
    <xsl:value-of select="substring(concat (wd:CF_Account_number_HSBC_Canada, $delimiter, $Var_CheckNumber, $Var_Payment,wd:Payment_Date, $delimiter, wd:Payment_Payee/@wd:Descriptor, $spaces),1,300)"/>
    <xsl:value-of select='$linefeed'/>
</xsl:template>

<xsl:template match="wd:Report_Data">
    <xsl:for-each-group select="wd:Report_Entry/wd:Payments_group" group-by="wd:CF_Account_number_HSBC_Canada">
        <xsl:apply-templates select="current-group()"/>
        <xsl:variable name="Counter" select="format-number(count(current-group()), '0000000000')"/>
        <xsl:variable name="Var_TotalSum" select="format-number(sum(current-group()/number(translate(wd:Payment_Total_Amount,'.',''))), '0000000000')"/>
        <xsl:value-of select="substring(concat ('T',wd:CF_Account_number_HSBC_Canada, $delimiter,$delimiter,$delimiter,$delimiter,$delimiter,$Counter,$delimiter,$delimiter,$delimiter,$delimiter, $Var_TotalSum, $spaces),1,300)"/>
        <xsl:value-of select='$linefeed'/>
    </xsl:for-each-group>
</xsl:template>

2 个答案:

答案 0 :(得分:1)

考虑一个递归模板,以添加所需的空格以填充文本输出。由于您没有提供可复制的示例(即原始XML),请考虑以下示例,该示例将每个文本值填充为10个字符的长度:

XML

<?xml version="1.0" encoding="utf-8" ?>
<root>
    <languages type="special purpose">
        <language>xslt</language>
        <language>sql</language>
        <language>css</language>
    </languages>
    <languages type="general purpose">
        <language>python</language>
        <language>java</language>
        <language>c#</language>
    </languages>
</root>

XSLT (请参阅注释以根据您的实际XSLT进行调整)

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="1.0">
     <xsl:output method="xml" indent="yes"/>

    <!-- IDENTITY TRANSFORM -->
    <!-- REPLACE WITH YOUR HIGHER LEVEL TEMPLATES -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="language">
        <!-- BUILD SPACES CONDITIONAL ON LENGTH OF TEXT -->
        <!-- REPLACE text() YOUR substring(concat (...)) WITHOUT YOUR LONG $spaces) -->
        <xsl:variable name="spaces">
              <xsl:call-template name="repeat">
                <xsl:with-param name="spaces" select="string-length(text())"/>
              </xsl:call-template>
        </xsl:variable>
        <xsl:copy>
            <!-- PAD TEXT WITH SPACES -->
            <xsl:value-of select="concat(text(), $spaces)"/>
        </xsl:copy>
    </xsl:template>    

    <!-- RECURSIVE TEMPLATE -->
    <xsl:template name="repeat">
        <xsl:param name="spaces"/>
        <xsl:param name="n"><xsl:value-of select="$spaces"/></xsl:param>

        <!-- REPLACE 10 FOR YOUR 300 -->
        <xsl:if test="$n &lt;= 10">
            <!-- recursive call -->
            <xsl:call-template name="repeat">
                <xsl:with-param name="n" select="$n + 1" />
            </xsl:call-template> 
            <!-- REPLACE WITH ANY TEXT VALUE TO BE REPEATED -->      
            <xsl:text>&#x20;</xsl:text>
        </xsl:if>
    </xsl:template>

</xsl:stylesheet>

输出

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <languages type="special purpose">
        <language>xslt      </language>
        <language>sql       </language>
        <language>css       </language>
    </languages>
    <languages type="general purpose">
        <language>python    </language>
        <language>java      </language>
        <language>c#        </language>
    </languages>
</root>

XSLT Demo

答案 1 :(得分:1)

使用for-each-group建议您使用XSLT 3或2处理器,以便构造可以使用XPath 3或2的$n空间的字符串,例如string-join((1 to $n)!' ')(在XPath 3.1中也可以表示为(1 to $n)!' '=>string-join())或XSLT / XPath 2中的string-join(for $i in 1 to $n return ' ', '')