带有前导空格的XSLT 2.0 Pad字符串 - for-each出错

时间:2016-06-10 14:19:33

标签: c# xml xslt

我使用XSLT表将XML文件转换为带有文本文件的固定文件。

我的解决方案"使固定宽度字段用前导零填充它们,我尝试使用以下模板执行此操作

<xsl:template name="padout" >
<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:call-template name="padout">
  <xsl:with-param name="str" select="ancestor::PMI/Home/Name"/>
  <xsl:with-param name="chr" xml:space="default"/>
  <xsl:with-param name="len" select="30"/>
</xsl:call-template>

但我收到错误

表达式的预期结束,找到&#39;。

我假设它指的是&#34; to&#34;在每一行中。

我在VS2015的.NET 4.5.2应用程序中使用它

var transform = new XslCompiledTransform();
transform.Load(path);
using (StringWriter writer = new StringWriter())
{
     transform.Transform(pmi, null, writer);
}

我没有XSLT的经验,而且我现在感到沮丧,因为我整个下午都在与这个人搏斗,Google不是我的朋友!

编辑: 如果VS2015无法处理XSLT 2.0,那么有人可以建议在1.0中执行此操作吗?

1 个答案:

答案 0 :(得分:1)

以下是将模板重写为XSLT 1.0递归模板:

<xsl:template name="pad" >
    <xsl:param name="string"/>
    <xsl:param name="length"/>
    <xsl:param name="char" select="'0'"/>
    <xsl:choose>
        <xsl:when test="string-length($string) >= $length">
            <xsl:value-of select="substring($string, 1, $length)"/>
        </xsl:when>
        <xsl:otherwise>
            <xsl:call-template name="pad">
                <xsl:with-param name="string" select="concat($char, $string)"/>
                <xsl:with-param name="length" select="$length"/>
            </xsl:call-template>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

电话示例:

<test>
    <xsl:call-template name="pad">
        <xsl:with-param name="string" select="'ABC'"/>
        <xsl:with-param name="length" select="30"/>
    </xsl:call-template>
</test>

结果:

<test>000000000000000000000000000ABC</test>

注意

这是一种非常低效的方法。如图here所示,使用“零”银行会更好(255个字符当然是合理的)。对于非常大数,您可以使用基于二进制的递归。