XSLT将文本数据拆分为多行组

时间:2014-07-11 09:09:58

标签: xslt xslt-2.0 xslt-grouping

我正在尝试编写一个XSLT代码,该代码分割具有多行的文本数据,并生成一个XML,其中包含来自文本数据的多个固定行数的组。

例如,如果我的输入XML是这样的

<?xml version="1.0" encoding="UTF-8"?>
<csv>
    <data>Id,Name,Address,Location,Extid,contact
          1,raagu1,hosakote1,bangalore1,123,contact1
          2,raagu2,hosakote2,bangalore2,123,contact2
          3,raagu3,hosakote3,bangalore3,123,contact3
          4,raag4,hosakote4,bangalore4,123,contact4
          5,raagu5,hosakote5,bangalore5,123,contact5
          6,raagu6,hosakote6,bangalore6,123,contact6
          7,raagu7,hosakote7,bangalore7,123,contact7
    </data>
</csv>

元素data下的文本数据告诉,第一行(Id,Name,Address,Location,Extid,contact)是标题,其余行是与标题字段对应的数据。

当我说线的固定长度是4 i时,e。一组4个数据集, 那么我的输出XML应该是这样的。

<?xml version="1.0" encoding="UTF-8"?>
<csv>
    <data>
        Id,Name,Address,Location,Extid,contact
        1,raagu1,hosakote1,bangalore1,123,contact1
        2,raagu2,hosakote2,bangalore2,123,contact2
        3,raagu3,hosakote3,bangalore3,123,contact3
        4,raag4,hosakote4,bangalore4,123,contact4
    </data>
    <data>
        Id,Name,Address,Location,Extid,contact
        5,raagu5,hosakote5,bangalore5,123,contact5
        6,raagu6,hosakote6,bangalore6,123,contact6
        7,raagu7,hosakote7,bangalore7,123,contact6
    </data>
</csv>

为了达到这个目的,我已经在xslt脚本上进行了探索并尝试了遵循XSLT

 <xsl:stylesheet version = "2.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform">

<xsl:output indent="yes" method="xml" encoding="UTF-8"/>

<xsl:template match = "/csv/data">

    <xsl:variable name="header" select="substring-before(.,'&#10;')"/>
    <xsl:variable name="data" select="substring-after(.,'&#10;')"/>

    <csv>

        <xsl:for-each select = "tokenize($data, '\n')">

            <xsl:variable name="count" select="position()"/>

            <data>
                <xsl:value-of select="$header"/>
                <xsl:text>&#10;</xsl:text>
                <xsl:sequence select = "."/>
            </data>

        </xsl:for-each>

    </csv>

</xsl:template>
</xsl:stylesheet>

有了这个,我得到的输出是

<?xml version="1.0" encoding="UTF-8"?>
<csv>
<data>
    Id,Name,Address,Location,Extid,contact
    1,raagu1,hosakote1,bangalore1,123,contact1
</data>
<data>
    Id,Name,Address,Location,Extid,contact
    2,raagu2,hosakote2,bangalore2,123,contact2
</data>
<data>
    Id,Name,Address,Location,Extid,contact
    3,raagu3,hosakote3,bangalore3,123,contact3
</data>
<data>
    Id,Name,Address,Location,Extid,contact
    4,raag4,hosakote4,bangalore4,123,contact4
</data>
<data>
    Id,Name,Address,Location,Extid,contact
    5,raagu5,hosakote5,bangalore5,123,contact5
</data>
<data>
    Id,Name,Address,Location,Extid,contact
    6,raagu6,hosakote6,bangalore6,123,contact6
</data>
<data>
    Id,Name,Address,Location,Extid,contact
    7,raagu7,hosakote7,bangalore7,123,contact7
</data>
</csv>

我无法完全理解,因为它正在分组的每一行。我想我错过了一些与连接有关的事情。我正在寻找一些帮助,看看它们是否是xslt中的任何函数,我们可以将文本拆分为多个组行,并为每个组创建一个具有非常好性能的单个元素?我对xslt 2.0函数没问题。该代码甚至可以用于1,00,000多个数据集。

感谢

Raagu

2 个答案:

答案 0 :(得分:3)

您真的想要创建继续使用逗号分隔数据和行分隔数据的XML结果格式吗?我会考虑清理数据并使用XML正确标记。

但至于分组,这是一个例子:

<xsl:stylesheet version = "2.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  exclude-result-prefixes="xs">

<xsl:param name="chunk-size" select="4" as="xs:integer"/>

<xsl:output indent="yes" method="xml" encoding="UTF-8"/>

<xsl:template match = "/csv/data">

    <xsl:variable name="header" select="substring-before(.,'&#10;')"/>
    <xsl:variable name="data" select="substring-after(.,'&#10;')"/>

    <csv>

        <xsl:for-each-group select = "tokenize($data, '\n')" group-adjacent="(position() - 1) idiv $chunk-size">



            <data>
                <xsl:value-of select="$header"/>
                <xsl:text>&#10;</xsl:text>
                <xsl:value-of select = "current-group()" separator="&#10;"/>
            </data>

        </xsl:for-each-group>

    </csv>

</xsl:template>
</xsl:stylesheet>

答案 1 :(得分:2)

这是一个基本的解决方案(不是群组相邻的),手动元素创建 - 不是很漂亮,但是有效且全面。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes" method="xml" encoding="UTF-8"/>

    <xsl:template match="/csv/data">
        <xsl:variable name="header" select="substring-before(.,'&#10;')"/>
        <xsl:variable name="data" select="substring-after(.,'&#10;')"/>
        <xsl:variable name="numberOfRows" select="4"/>
        <csv>
            <xsl:for-each select="tokenize($data, '\n')">
                <xsl:variable name="count" select="position()-1"/>
                <xsl:variable name="modulo" select="$count mod $numberOfRows"/>
                <xsl:if test="$modulo = 0">
                    <xsl:text disable-output-escaping="yes">&lt;data></xsl:text>
                    <xsl:value-of select="$header"/>
                    <xsl:text>&#10;</xsl:text>
                </xsl:if>
                <xsl:sequence select="."/>
                <xsl:text>&#10;</xsl:text>

                <xsl:if test="$modulo = ($numberOfRows - 1)">
                    <xsl:text disable-output-escaping="yes">&lt;/data></xsl:text>
                </xsl:if>

            </xsl:for-each>
        </csv>
    </xsl:template>

</xsl:stylesheet>