2016-06-10 23 views
0

我正在使用XSLT工作表将XML文件转换为带有文本文件的固定文件。XSLT 2.0带前导空格的填充字符串 - for-each中的错误

我的“解决方案”,使固定宽度的字段是垫出来带前导零的,我已经尝试用下面的模板

<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> 

但我得到一个错误说

预计年底Ø表达,发现'到'。

我假设它指的是每行中的“to”。

我在.NET 4.5.2应用程序在VS2015

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?

+0

您确定您使用的是像Saxon 9,XmlPrime,Exselt或Altova这样的XSLT 2.0处理器吗? –

+0

我正在使用Visual Studio 15和一个面向.NET 4.5.2的项目。 var transform = new XslCompiledTransform(); transform.Load(path); transform.Transform(pmi,null,writer); – MarkBrad

+0

这是一款XSLT 1.0处理器。要在XSLT 1.0中进行填充,您需要一个*递归*命名模板 - 或者简单地执行下面的操作:http://stackoverflow.com/questions/31805587/pad-value-with-fix-length-xslt/31805975#31805975 –

回答

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个字符肯定是合理的)。对于非常大的,您可以使用基于二进制的递归。