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

Posted

技术标签:

【中文标题】如何在 xslt 中添加空格并将记录限制为 300 个字符【英文标题】:How to add spaces in and restrict records to 300 characters in xslt 【发布时间】:2019-05-17 05:31:57 【问题描述】:

我写了一个 xslt 来将 xml 转换为 CSV。本质上,xslt 创建 300 个字符的记录并添加空格,直到记录达到 300 个限制(如果没有数据)。下面是 xslt,它符合我的目的。但我必须使用一个变量 Spaces,其中包含 300 个空格,并在记录中使用。

我的问题是我很想知道是否有比我采用的方法更简单的方法。下面是我的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>

【问题讨论】:

【参考方案1】:

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

【讨论】:

【参考方案2】:

考虑使用递归模板来添加所需的空格来填充文本输出。由于您没有提供可重现的示例(即原始 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 (看cmets根据你的实际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

【讨论】:

以上是关于如何在 xslt 中添加空格并将记录限制为 300 个字符的主要内容,如果未能解决你的问题,请参考以下文章

XSLT 如何组合模板并将现有字段添加到某些元素

我们如何识别一组节点并将该组添加到另一个 XSLT 中 XML 源结构不同的节点?

如何在 XSLT 中保留 xml 元素的空格

拆分字符串中的第一个空格和最后一个空格并将输出的大小限制为3

XSLT 1.0 删除前导零并将小数点添加到值

如何使用 XSLT 在 xml 文件中查找元素并将其放置在另一个标记中?