我有以下节点集片段:
<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-group
<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>
我需要检查每个级别并对每个不同的值进行分组。
答案 0 :(得分:0)
将代码放入递归函数中:
<?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>