Как заполнить пустое пространство с помощью XSLT?

Я использую XSLT для преобразования XML в текстовый файл с разделителями косой чертой. В части моего xml мне нужно создать следующее:

HEADING
/1    /2                   /3       /4     /5 /6        /7
/data /data                /data    /dat   / 1/data     /data

Где есть заголовок, а числа - это заголовки столбцов со строками данных под ними. Расстояние между столбцами должно быть одинаковым, но данные могут иметь длину меньше необходимого расстояния между столбцами. Я использую это, чтобы получить значение:

<xsl:value-of select="package_identification"/>

Что я могу сделать, чтобы заполнить оставшееся пространство пробелами?


person kbreezy04    schedule 11.07.2013    source источник


Ответы (2)


Вот два пути, о которых я могу думать.

Ввод XML

<test>
    <row>
        <entry>data</entry>
        <entry>dataaaa</entry>
        <entry>data</entry>     
    </row>
    <row>
        <entry>datadata</entry>
        <entry>datad</entry>
        <entry>da</entry>       
    </row>
</test>

Первый XSLT 2.0

Здесь используются буквальные пробелы для представления ширины столбца. Он также использует substring(), чтобы убрать то, что ему не нужно ...

<xsl:stylesheet version="2.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>
    <xsl:strip-space elements="*"/>

    <xsl:variable name="colwidths" as="element()">
        <colwidths>
            <col val="                 "/>                 
            <col val="         "/>
            <col val="                       "/>                         
        </colwidths>
    </xsl:variable>

    <xsl:template match="row">
        <xsl:apply-templates/>
        <xsl:text>&#xA;</xsl:text>
    </xsl:template>

    <xsl:template match="entry">
        <xsl:variable name="currPos" select="position()"/>
        <xsl:value-of select="concat('/',.,substring($colwidths/col[$currPos]/@val,string-length(.)))"/>
    </xsl:template>

</xsl:stylesheet>

Второй XSLT 2.0

Это похоже, но использует цифры для представления ширины столбца и использует xsl:for-each для вывода необходимых пробелов ...

<xsl:stylesheet version="2.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xsl:output method="text"/>
    <xsl:strip-space elements="*"/>

    <xsl:variable name="colwidths" as="element()">
        <colwidths>
            <col val="17"/>                 
            <col val="9"/>
            <col val="23"/>                         
        </colwidths>
    </xsl:variable>

    <xsl:template match="row">
        <xsl:apply-templates/>
        <xsl:text>&#xA;</xsl:text>
    </xsl:template>

    <xsl:template match="entry">
        <xsl:variable name="currPos" select="position()"/>
        <xsl:value-of select="concat('/',.)"/>
        <xsl:for-each select="0 to xs:integer($colwidths/col[$currPos]/@val - string-length(.))">
            <xsl:text> </xsl:text>
        </xsl:for-each>
    </xsl:template>

</xsl:stylesheet>

Оба они производят следующий результат:

/data              /dataaaa   /data                    
/datadata          /datad     /da                      
person Daniel Haley    schedule 11.07.2013

Если вы можете использовать EXSLT, используйте функцию str: padding: http://www.exslt.org/str/functions/padding/index.html

Предполагая, что вы хотите, чтобы столбец был шириной 10 символов, работая с вашей строкой XSLT:

<xsl:value-of select="package_identification"/>
<xsl:value-of select="str:padding(10 - string-length(package_identification))"/>

Обязательно объявите xmlns: str = "http://exslt.org/strings", желательно в элементе xsl: stylesheet.

Если вы не можете использовать EXSLT, определите шаблон рекурсивного заполнения:

<xsl:template name="padding">
  <xsl:param name="length"/>
  <xsl:param name="string" select="' '"/>
  <xsl:value-of select="$string"/>
  <xsl:if test="$length > 1">
    <xsl:call-template name="padding">
      <xsl:with-param name="length" select="$length - 1"/>
      <xsl:with-param name="string" select="$string"/>
    </xsl:call-template>
  </xsl:if>
</xsl:template>

Затем используйте это так:

<xsl:value-of select="package_identification"/>
<xsl:call-template name="padding">
  <xsl:with-param name="length" select="10 - string-length(package_identification)"/>
</xsl:call-template>
person Shaun McCance    schedule 11.07.2013