我正在尝试编写一个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(.,' ')"/>
<xsl:variable name="data" select="substring-after(.,' ')"/>
<csv>
<xsl:for-each select = "tokenize($data, '\n')">
<xsl:variable name="count" select="position()"/>
<data>
<xsl:value-of select="$header"/>
<xsl:text> </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
答案 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(.,' ')"/>
<xsl:variable name="data" select="substring-after(.,' ')"/>
<csv>
<xsl:for-each-group select = "tokenize($data, '\n')" group-adjacent="(position() - 1) idiv $chunk-size">
<data>
<xsl:value-of select="$header"/>
<xsl:text> </xsl:text>
<xsl:value-of select = "current-group()" separator=" "/>
</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(.,' ')"/>
<xsl:variable name="data" select="substring-after(.,' ')"/>
<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"><data></xsl:text>
<xsl:value-of select="$header"/>
<xsl:text> </xsl:text>
</xsl:if>
<xsl:sequence select="."/>
<xsl:text> </xsl:text>
<xsl:if test="$modulo = ($numberOfRows - 1)">
<xsl:text disable-output-escaping="yes"></data></xsl:text>
</xsl:if>
</xsl:for-each>
</csv>
</xsl:template>
</xsl:stylesheet>