在 XSLT 1.0 中根据批量大小输出新行
Outputting a new row based on batch size in XSLT 1.0
我正在使用 xslt 将 xml 转换为竖线分隔文件,xslt 版本 1.0。一个人可以有很多类。我正在努力弄清楚如何在 1.0 版中以 5 类 为一组创建新行?
示例代码片段
<root>
<Person>
<Name>Doug</Name>
<Class>
<ClassID>AS</ClassID>
</Class>
<Class>
<ClassID>BA</ClassID>
</Class>
<Class>
<ClassID>ZX</ClassID>
</Class>
<Class>
<ClassID>MSN</ClassID>
</Class>
<Class>
<ClassID>ABSN</ClassID>
</Class>
<Class>
<ClassID>FS</ClassID>
</Class>
</Person>
<Person>
<Name>Amy</Name>
<Class>
<ClassID>AS</ClassID>
</Class>
<Class>
<ClassID>BA</ClassID>
</Class>
</Person>
<Person>
<Name>Charlotte</Name>
<Class>
<ClassID>BA</ClassID>
</Class>
</Person>
<Person>
<Name>Betty</Name>
<Class>
<ClassID>ZX</ClassID>
</Class>
</Person>
</root>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.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="linefeed" select="'
'"/>
<xsl:template match="/">
<File>
<Body>
<xsl:apply-templates select="root/Person"/>
</Body>
</File>
</xsl:template>
<xsl:template match="root/Person">
<xsl:value-of select="Name"/>
<xsl:for-each select="Class">
<xsl:text>|</xsl:text>
<xsl:value-of select="ClassID" />
</xsl:for-each>
<xsl:value-of select="$linefeed"/>
</xsl:template>
</xsl:stylesheet>
而不是这个
Doug|AS|BA|ZX|MSN|ABSN|FS
Amy|AS|BA
Charlotte|BA
Betty|ZX
我需要这个 - 道格现在有两行,因为他有超过 5 类(只有 5 类 可以放在一行上)。这需要是动态的,可能有 100 类.
Doug|AS|BA|ZX|MSN|ABSN
Doug|FS
Amy|AS|BA
Charlotte|BA
Betty|ZX
我一直在兜圈子-请帮忙!
您可以使用这样的递归模板来完成:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.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="linefeed" select="'
'"/>
<xsl:template match="/">
<xsl:apply-templates select="root/Person"/>
</xsl:template>
<xsl:template match="Person">
<xsl:call-template name="PersonOutput">
<xsl:with-param name="index" select="1"/>
<xsl:with-param name="person" select="."/>
</xsl:call-template>
</xsl:template>
<xsl:template name="PersonOutput">
<xsl:param name="index"/>
<xsl:param name="person"/>
<xsl:if test="$index=1 or ($index mod 5)=1">
<xsl:value-of select="$linefeed"/>
<xsl:value-of select="$person/Name"/>
</xsl:if>
<xsl:text>|</xsl:text>
<xsl:value-of select="$person/Class[$index]/ClassID"/>
<xsl:if test="$person/Class[$index]/following-sibling::Class">
<xsl:call-template name="PersonOutput">
<xsl:with-param name="index" select="$index+1"/>
<xsl:with-param name="person" select="$person"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
这里有一个相当简单的查看方式:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/root">
<xsl:for-each select="Person">
<xsl:variable name="name" select="Name" />
<xsl:for-each select="Class[position() mod 5 = 1]" >
<xsl:value-of select="$name" />
<xsl:for-each select=". | following-sibling::Class[position() < 5]">
<xsl:text>|</xsl:text>
<xsl:value-of select="ClassID" />
</xsl:for-each>
<xsl:text> </xsl:text>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
我正在使用 xslt 将 xml 转换为竖线分隔文件,xslt 版本 1.0。一个人可以有很多类。我正在努力弄清楚如何在 1.0 版中以 5 类 为一组创建新行?
示例代码片段
<root>
<Person>
<Name>Doug</Name>
<Class>
<ClassID>AS</ClassID>
</Class>
<Class>
<ClassID>BA</ClassID>
</Class>
<Class>
<ClassID>ZX</ClassID>
</Class>
<Class>
<ClassID>MSN</ClassID>
</Class>
<Class>
<ClassID>ABSN</ClassID>
</Class>
<Class>
<ClassID>FS</ClassID>
</Class>
</Person>
<Person>
<Name>Amy</Name>
<Class>
<ClassID>AS</ClassID>
</Class>
<Class>
<ClassID>BA</ClassID>
</Class>
</Person>
<Person>
<Name>Charlotte</Name>
<Class>
<ClassID>BA</ClassID>
</Class>
</Person>
<Person>
<Name>Betty</Name>
<Class>
<ClassID>ZX</ClassID>
</Class>
</Person>
</root>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.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="linefeed" select="'
'"/>
<xsl:template match="/">
<File>
<Body>
<xsl:apply-templates select="root/Person"/>
</Body>
</File>
</xsl:template>
<xsl:template match="root/Person">
<xsl:value-of select="Name"/>
<xsl:for-each select="Class">
<xsl:text>|</xsl:text>
<xsl:value-of select="ClassID" />
</xsl:for-each>
<xsl:value-of select="$linefeed"/>
</xsl:template>
</xsl:stylesheet>
而不是这个
Doug|AS|BA|ZX|MSN|ABSN|FS
Amy|AS|BA
Charlotte|BA
Betty|ZX
我需要这个 - 道格现在有两行,因为他有超过 5 类(只有 5 类 可以放在一行上)。这需要是动态的,可能有 100 类.
Doug|AS|BA|ZX|MSN|ABSN
Doug|FS
Amy|AS|BA
Charlotte|BA
Betty|ZX
我一直在兜圈子-请帮忙!
您可以使用这样的递归模板来完成:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.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="linefeed" select="'
'"/>
<xsl:template match="/">
<xsl:apply-templates select="root/Person"/>
</xsl:template>
<xsl:template match="Person">
<xsl:call-template name="PersonOutput">
<xsl:with-param name="index" select="1"/>
<xsl:with-param name="person" select="."/>
</xsl:call-template>
</xsl:template>
<xsl:template name="PersonOutput">
<xsl:param name="index"/>
<xsl:param name="person"/>
<xsl:if test="$index=1 or ($index mod 5)=1">
<xsl:value-of select="$linefeed"/>
<xsl:value-of select="$person/Name"/>
</xsl:if>
<xsl:text>|</xsl:text>
<xsl:value-of select="$person/Class[$index]/ClassID"/>
<xsl:if test="$person/Class[$index]/following-sibling::Class">
<xsl:call-template name="PersonOutput">
<xsl:with-param name="index" select="$index+1"/>
<xsl:with-param name="person" select="$person"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
这里有一个相当简单的查看方式:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/root">
<xsl:for-each select="Person">
<xsl:variable name="name" select="Name" />
<xsl:for-each select="Class[position() mod 5 = 1]" >
<xsl:value-of select="$name" />
<xsl:for-each select=". | following-sibling::Class[position() < 5]">
<xsl:text>|</xsl:text>
<xsl:value-of select="ClassID" />
</xsl:for-each>
<xsl:text> </xsl:text>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>