XSLT 根据节点的位置重复打印节点的值
XSLT to print values of a node based on its position repetitively
我必须在 xslt 1.0 或 xslt 2.0 中转换此示例 xml
来源XML
<root>
<group>
<subgroup>
<name>AAA1</name>
</subgroup>
<subgroup>
<name>AAA2</name>
</subgroup>
<subgroup>
<name>AAA3</name>
</subgroup>
</group>
<group>
<subgroup>
<name>BB1</name>
</subgroup>
<subgroup>
<name>BB2</name>
</subgroup>
<subgroup>
<name>BB3</name>
</subgroup>
</group>
</root>
需要XML输出
<?xml version="1.0" encoding="UTF-8"?>
<root>
<group>AAA1|BB1|AAA2|BB2|AAA3|BB3</group>
</root>
我尝试了以下 xslt:
XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<xsl:template match="root">
<root>
<group>
<xsl:for-each select="group">
<xsl:for-each select="subgroup">
<xsl:choose>
<xsl:when test="position() != last()">
<xsl:value-of select="name" /><xsl:text>|</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="name" />
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:for-each>
</group>
</root>
</xsl:template>
</xsl:stylesheet>
电流输出
<?xml version="1.0" encoding="UTF-8"?>
<root>
<group>AAA1|AAA2|AAA3BB1|BB2|BB3</group>
</root>
我该怎么做?我应该创建一个模板并递归调用它吗?
您只需要处理 spec
组元素中的 一个 组,并按位置从另一组中拉出相应的 spec
:
<root>
<group>
<xsl:for-each select="group[1]/spec">
<xsl:variable name="pos" select="position()"/>
<xsl:for-each select="../../group">
<!-- put a | in front of everything but the first spec in the first group -->
<xsl:if test="$pos > 1 or position() > 1">|</xsl:if>
<xsl:value-of select="spec[$pos]/name" />
</xsl:for-each>
</xsl:for-each>
</group>
</root>
XSLT 2.0 版本:在 2.0 中,您可以使用单个 value-of
:
<group>
<xsl:value-of select="for $n in 1 to count(group[1]/spec)
return (group/spec[$n]/name)" separator="|" />
</group>
想到这个:
选取除第一组以外的所有其他组,然后迭代第一组的所有规格,同时从所有其他组选取相应的规格
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<xsl:template match="root">
<root>
<group>
<xsl:variable name="firstExcludeGroups" select="//group[position()!=1]"/>
<xsl:variable name="firstGroup" select="//group[position()=1]"/>
<xsl:for-each select="$firstGroup/spec">
<xsl:value-of select="name"/>
<xsl:text>|</xsl:text>
<xsl:variable name="curPosition" select="position()"/>
<xsl:for-each select="$firstExcludeGroups/spec">
<xsl:if test="$curPosition=position()">
<xsl:value-of select="name"/>
</xsl:if>
</xsl:for-each>
</xsl:for-each>
</group>
</root>
</xsl:template>
</xsl:stylesheet>
我必须在 xslt 1.0 或 xslt 2.0 中转换此示例 xml 来源XML
<root>
<group>
<subgroup>
<name>AAA1</name>
</subgroup>
<subgroup>
<name>AAA2</name>
</subgroup>
<subgroup>
<name>AAA3</name>
</subgroup>
</group>
<group>
<subgroup>
<name>BB1</name>
</subgroup>
<subgroup>
<name>BB2</name>
</subgroup>
<subgroup>
<name>BB3</name>
</subgroup>
</group>
</root>
需要XML输出
<?xml version="1.0" encoding="UTF-8"?>
<root>
<group>AAA1|BB1|AAA2|BB2|AAA3|BB3</group>
</root>
我尝试了以下 xslt:
XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<xsl:template match="root">
<root>
<group>
<xsl:for-each select="group">
<xsl:for-each select="subgroup">
<xsl:choose>
<xsl:when test="position() != last()">
<xsl:value-of select="name" /><xsl:text>|</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="name" />
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:for-each>
</group>
</root>
</xsl:template>
</xsl:stylesheet>
电流输出
<?xml version="1.0" encoding="UTF-8"?>
<root>
<group>AAA1|AAA2|AAA3BB1|BB2|BB3</group>
</root>
我该怎么做?我应该创建一个模板并递归调用它吗?
您只需要处理 spec
组元素中的 一个 组,并按位置从另一组中拉出相应的 spec
:
<root>
<group>
<xsl:for-each select="group[1]/spec">
<xsl:variable name="pos" select="position()"/>
<xsl:for-each select="../../group">
<!-- put a | in front of everything but the first spec in the first group -->
<xsl:if test="$pos > 1 or position() > 1">|</xsl:if>
<xsl:value-of select="spec[$pos]/name" />
</xsl:for-each>
</xsl:for-each>
</group>
</root>
XSLT 2.0 版本:在 2.0 中,您可以使用单个 value-of
:
<group>
<xsl:value-of select="for $n in 1 to count(group[1]/spec)
return (group/spec[$n]/name)" separator="|" />
</group>
想到这个:
选取除第一组以外的所有其他组,然后迭代第一组的所有规格,同时从所有其他组选取相应的规格
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<xsl:template match="root">
<root>
<group>
<xsl:variable name="firstExcludeGroups" select="//group[position()!=1]"/>
<xsl:variable name="firstGroup" select="//group[position()=1]"/>
<xsl:for-each select="$firstGroup/spec">
<xsl:value-of select="name"/>
<xsl:text>|</xsl:text>
<xsl:variable name="curPosition" select="position()"/>
<xsl:for-each select="$firstExcludeGroups/spec">
<xsl:if test="$curPosition=position()">
<xsl:value-of select="name"/>
</xsl:if>
</xsl:for-each>
</xsl:for-each>
</group>
</root>
</xsl:template>
</xsl:stylesheet>