我有以下节点集片段:
<category value="Library">
<category value="PACS">
<category value="IMPAX (PACS)">
<category value="Reporting"/>
</category>
</category>
</category>
<category value="Library">
<category value="Enterprise Imaging">
<category value="Desktops"/>
</category>
</category>
<category value="Library">
<category value="PACS">
<category value="IMPAX (PACS)"/>
</category>
</category>它是由以下代码生成的:
<xsl:template name="categories">
<xsl:param name="topicmeta"/>
<xsl:variable name="VarCategories">
<xsl:for-each select="map/topicmeta/category">
<xsl:if test="contains(./data/@value, 'Library')">
<xsl:if
test="string-length(./data/@value) - string-length(translate(./data/@value, '/', '')) > 1">
<xsl:call-template name="category">
<xsl:with-param name="category" select="./data/@value"/>
</xsl:call-template>
</xsl:if>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:call-template name="outputCategories">
<xsl:with-param name="categories" select="$VarCategories"/>
</xsl:call-template>
</xsl:template> 我需要输出:
<category value="Library">
<category value="PACS">
<category value="IMPAX (PACS)">
<category value="Reporting"/>
</category>
</category>
<category value="Enterprise Imaging">
<category value="Desktops"/>
</category>
</category>我正在尝试使用for-each组
<xsl:template name="outputCategories">
<xsl:param name="categories"/>
<xsl:element name="categories">
<xsl:for-each-group select="$categories/*" group-adjacent="@value">
<xsl:sort select="@value"></xsl:sort>
<xsl:copy-of select="." />
</xsl:for-each-group>
</xsl:element>
</xsl:template>这给了我:
<category value="Library">
<category value="PACS">
<category value="IMPAX (PACS)">
<category value="Reporting"/>
</category>
</category>
我需要检查每个级别,并对每个不同的值进行分组。
发布于 2016-02-02 00:53:31
将您的代码放入递归函数中:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="mf xs">
<xsl:output indent="yes"/>
<xsl:function name="mf:group" as="element(category)*">
<xsl:param name="categories" as="element(category)*"/>
<xsl:for-each-group select="$categories" group-by="@value">
<category value="{current-grouping-key()}">
<xsl:sequence select="mf:group(current-group()/category)"/>
</category>
</xsl:for-each-group>
</xsl:function>
<xsl:param name="cats">
<category value="Library">
<category value="PACS">
<category value="IMPAX (PACS)">
<category value="Reporting"/>
</category>
</category>
</category>
<category value="Library">
<category value="Enterprise Imaging">
<category value="Desktops"/>
</category>
</category>
<category value="Library">
<category value="PACS">
<category value="IMPAX (PACS)"/>
</category>
</category>
</xsl:param>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<xsl:sequence select="mf:group($cats/category)"/>
</xsl:template>
</xsl:transform>请访问http://xsltransform.net/3NJ38ZB。
如果您还需要排序,则将函数更改为例如
<xsl:function name="mf:group" as="element(category)*">
<xsl:param name="categories" as="element(category)*"/>
<xsl:for-each-group select="$categories" group-by="@value">
<xsl:sort select="current-grouping-key()"/>
<category value="{current-grouping-key()}">
<xsl:sequence select="mf:group(current-group()/category)"/>
</category>
</xsl:for-each-group>
</xsl:function>至于您在注释中链接到的示例,它将其创建的category元素放在FO名称空间中,您必须通过执行以下操作来避免这种情况
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns="http://www.w3.org/1999/XSL/Format"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:exsl="http://exslt.org/common"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="xs exsl mf">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="status"/>
<xsl:param name="draft"/>
<xsl:template match="/">
<index>
<xsl:call-template name="categories"> </xsl:call-template>
</index>
</xsl:template>
<xsl:template name="categories">
<xsl:param name="topicmeta"/>
<xsl:variable name="VarCategories">
<xsl:for-each select="map/topicmeta/category">
<xsl:if test="contains(./data/@value, 'Library')">
<xsl:if
test="string-length(./data/@value) - string-length(translate(./data/@value, '/', '')) > 1">
<xsl:call-template name="category">
<xsl:with-param name="category" select="./data/@value"/>
</xsl:call-template>
</xsl:if>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:sequence select="mf:group($VarCategories/category)"/>
</xsl:template>
<xsl:template name="category" xmlns="">
<xsl:param name="category"/>
<xsl:if test="string-length($category) > 0">
<xsl:element name="category">
<xsl:attribute name="value">
<xsl:choose>
<xsl:when test="substring-before($category, '/') = ''">
<xsl:value-of select="$category"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="substring-before($category, '/')"/>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:call-template name="category">
<xsl:with-param name="category" select="substring-after($category, '/')"/>
</xsl:call-template>
</xsl:element>
</xsl:if>
</xsl:template>
<xsl:function name="mf:group" as="element(category)*" xmlns="">
<xsl:param name="categories" as="element(category)*"/>
<xsl:for-each-group select="$categories" group-by="@value">
<xsl:sort select="current-grouping-key()"/>
<category value="{current-grouping-key()}">
<xsl:sequence select="mf:group(current-group()/category)"/>
</category>
</xsl:for-each-group>
</xsl:function>
</xsl:stylesheet>或者,您必须确保函数中的路径选择该名称空间中的元素:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns="http://www.w3.org/1999/XSL/Format"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:exsl="http://exslt.org/common"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="xs exsl mf">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="status"/>
<xsl:param name="draft"/>
<xsl:template match="/">
<index>
<xsl:call-template name="categories"> </xsl:call-template>
</index>
</xsl:template>
<xsl:template name="categories">
<xsl:param name="topicmeta"/>
<xsl:variable name="VarCategories">
<xsl:for-each select="map/topicmeta/category">
<xsl:if test="contains(./data/@value, 'Library')">
<xsl:if
test="string-length(./data/@value) - string-length(translate(./data/@value, '/', '')) > 1">
<xsl:call-template name="category">
<xsl:with-param name="category" select="./data/@value"/>
</xsl:call-template>
</xsl:if>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:sequence select="mf:group($VarCategories/*)"/>
</xsl:template>
<xsl:template name="category">
<xsl:param name="category"/>
<xsl:if test="string-length($category) > 0">
<xsl:element name="category">
<xsl:attribute name="value">
<xsl:choose>
<xsl:when test="substring-before($category, '/') = ''">
<xsl:value-of select="$category"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="substring-before($category, '/')"/>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:call-template name="category">
<xsl:with-param name="category" select="substring-after($category, '/')"/>
</xsl:call-template>
</xsl:element>
</xsl:if>
</xsl:template>
<xsl:function name="mf:group" as="element(category)*" xpath-default-namespace="http://www.w3.org/1999/XSL/Format">
<xsl:param name="categories" as="element(category)*"/>
<xsl:for-each-group select="$categories" group-by="@value">
<xsl:sort select="current-grouping-key()"/>
<category value="{current-grouping-key()}">
<xsl:sequence select="mf:group(current-group()/category)"/>
</category>
</xsl:for-each-group>
</xsl:function>
</xsl:stylesheet>https://stackoverflow.com/questions/35135069
复制相似问题