2016-06-10 2 views
0

Я использую лист XSLT для преобразования XML-файла в файл с фиксированным текстом.XSLT 2.0 Pad string с ведущими пробелами - Ошибка для каждого

Мое «решение», чтобы сделать фиксированные поля ширины раздуть их с ведущими нулями, я пытаюсь сделать это с помощью следующего шаблона

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

Но я получаю сообщение об ошибке говорящее

Ожидаемый конец O f выражение, найденное '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 не мой друг на этом!

EDIT: Если VS2015 не может обрабатывать XSLT 2.0, может ли кто-нибудь предложить способ сделать это в 1.0?

+0

Вы уверены, что используете такой процессор XSLT 2.0, как Saxon 9, XmlPrime, Exselt или Altova? –

+0

Я использую Visual Studio 15 с таргетингом на проект .NET 4.5.2. var transform = new XslCompiledTransform(); transform.Load (путь); 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 символов, безусловно, в пределах разумного). Для очень больших чисел, вы можете использовать двоичную рекурсию.

Смежные вопросы