XSLT 1.0分组具有相同名称的多个元素 [英] XSLT 1.0 Grouping with multiple elements with same name
问题描述
我有一个类似-
<resultset>
<hit>
<content>
<ITEM>
<TITLE>Office Cleaning</TITLE>
<DESCRIPTION>blah blah blah</DESCRIPTION>
<Hierarchy>level1A:level2A:level3A</Hierarchy>
<Hierarchy>level1B:level2B:level3B</Hierarchy>
</ITEM>
</content>
</hit>
<hit>
<content>
<ITEM>
<TITLE>Office Cleaning1</TITLE>
<DESCRIPTION>blah blah blah</DESCRIPTION>
<Hierarchy>level1A:level2A:level3A</Hierarchy>
</ITEM>
</content>
</hit>
<hit>
<content>
<ITEM>
<TITLE>Office Cleaning2</TITLE>
<DESCRIPTION>blah blah blah</DESCRIPTION>
<Hierarchy>level1A:level2B:level3C</Hierarchy>
</ITEM>
</content>
</hit>
</resultset>
请注意,有多个层次结构元素,它们是level1:level2:level3的串联字符串 我希望将其转换为类似的内容-
Note that there are multiple hierarchy elements which is a concatenated string of level1:level2:level3 I am looking to transform this into something like this -
<TREE>
<LEVELS>
<LEVEL1 name="level1A">
<LEVEL2 name="level2A">
<LEVEL3 name="level3A">
<ITEM Name="Office Cleaning"/>
<ITEM Name="Office Cleaning1"/>
</LEVEL3>
</LEVEL2>
</LEVEL1>
<LEVEL1 name="level1B">
<LEVEL2 name="level2B">
<LEVEL3 name="level3B">
<ITEM Name="Office Cleaning"/>
</LEVEL3>
</LEVEL2>
</LEVEL1>
<LEVEL1 name="level1A">
<LEVEL2 name="level2B">
<LEVEL3 name="level3C">
<ITEM Name="Office Cleaning2"/>
</LEVEL3>
</LEVEL2>
</LEVEL1>
</LEVELS>
</TREE>
基本上,每个项目都具有多个与之相关的层次结构.我需要将它们组合在一起.
Basically each item has multiple hierachy associated with it. I need to group them together.
我只得到-
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:autn="http://schemas.autonomy.com/aci/">
<xsl:output method="xml" omit-xml-declaration="yes"/>
<xsl:key name="HIERARCHYLEVELS" match="resultset/hit/content/ITEM" use="HIERARCHY" />
<xsl:template match="/">
<TREE>
<xsl:for-each select="resultset/hit/content/ITEM[generate-id()=generate-id(key('HIERARCHYLEVELS', HIERARCHY)[1])]">
<xsl:for-each select="HIERARCHY">
<xsl:variable name="level" select="HIERARCHY"/>
<HIERARCHY name="{$level}" >
<xsl:variable name="name" select="TITLE"/>
<ITEM name="{$name}"/>
</HIERARCHY>
</xsl:for-each>
</xsl:for-each>
</TREE>
</xsl:template>
</xsl:stylesheet>
但是问题是我只得到第一个匹配的层次结构标记.例如我看不到办公室清洁1". 我该怎么做才能确保考虑所有层次结构元素?我仍然需要将其分为多个级别.
But the problem is I only get the first matching hierarchy tag. For e.g. I dont get to see "Office cleaning1". What can I do to make sure all hierarchy elements are considered? I still need to split it into various levels.
推荐答案
此转换:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kItemByHier" match="ITEM" use="Hierarchy"/>
<xsl:key name="kHierByVal" match="Hierarchy" use="."/>
<xsl:template match="/*">
<xsl:apply-templates select=
"*/*/*/Hierarchy[generate-id()=generate-id(key('kHierByVal',.)[1])]"/>
</xsl:template>
<xsl:template match="Hierarchy">
<xsl:call-template name="makeTree">
<xsl:with-param name="pHier" select="string()"/>
<xsl:with-param name="pItems" select="key('kItemByHier', .)"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="makeTree">
<xsl:param name="pHier"/>
<xsl:param name="pDepth" select="1"/>
<xsl:param name="pItems" select="/.."/>
<xsl:choose>
<xsl:when test="not($pHier)">
<xsl:for-each select="$pItems">
<ITEM name="{TITLE}"/>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<xsl:element name="LEVEL{$pDepth}">
<xsl:attribute name="name">
<xsl:value-of select="substring-before(concat($pHier,':'), ':')"/>
</xsl:attribute>
<xsl:call-template name="makeTree">
<xsl:with-param name="pHier"
select="substring-after($pHier,':')"/>
<xsl:with-param name="pDepth" select="$pDepth+1"/>
<xsl:with-param name="pItems" select="$pItems"/>
</xsl:call-template>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
应用于提供的XML文档:
<resultset>
<hit>
<content>
<ITEM>
<TITLE>Office Cleaning</TITLE>
<DESCRIPTION>blah blah blah</DESCRIPTION>
<Hierarchy>level1A:level2A:level3A</Hierarchy>
<Hierarchy>level1B:level2B:level3B</Hierarchy>
</ITEM>
</content>
</hit>
<hit>
<content>
<ITEM>
<TITLE>Office Cleaning1</TITLE>
<DESCRIPTION>blah blah blah</DESCRIPTION>
<Hierarchy>level1A:level2A:level3A</Hierarchy>
</ITEM>
</content>
</hit>
<hit>
<content>
<ITEM>
<TITLE>Office Cleaning2</TITLE>
<DESCRIPTION>blah blah blah</DESCRIPTION>
<Hierarchy>level1A:level2B:level3C</Hierarchy>
</ITEM>
</content>
</hit>
</resultset>
产生想要的正确结果:
<LEVEL1 name="level1A">
<LEVEL2 name="level2A">
<LEVEL3 name="level3A">
<ITEM name="Office Cleaning"/>
<ITEM name="Office Cleaning1"/>
</LEVEL3>
</LEVEL2>
</LEVEL1>
<LEVEL1 name="level1B">
<LEVEL2 name="level2B">
<LEVEL3 name="level3B">
<ITEM name="Office Cleaning"/>
</LEVEL3>
</LEVEL2>
</LEVEL1>
<LEVEL1 name="level1A">
<LEVEL2 name="level2B">
<LEVEL3 name="level3C">
<ITEM name="Office Cleaning2"/>
</LEVEL3>
</LEVEL2>
</LEVEL1>
这篇关于XSLT 1.0分组具有相同名称的多个元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!