我有这样的XML结构:
<Rootname>
<FIRST a="1" otherhattrs="whatever">
</FIRST>
<GROUPB a="b2" b="12" c="b456">
<SET NR="01">
<ENTRY type="10" otherhattr="whatever"/>
</SET>
<SET NR="02">
<ENTRY type="10" otherhattr="whatever"/>
<ENTRY type="10" otherhattr="whatever"/>
<ENTRY type="20" otherhattr="whatever"/>
</SET>
</GROUPB>
<GROUPC a="c3" b="23">
<SET NR="01">
<ENTRY type="10" otherhattr="whatever"/>
</SET>
<SET NR="02">
<ENTRY type="10" otherhattr="whatever"/>
<ENTRY type="30" otherhattr="whatever"/>
<ENTRY type="50" otherhattr="whatever"/>
</SET>
</GROUPC>
<GROUPD a="d4" b="34">
<SET NR="02">
<ENTRY type="10" otherhattr="whatever"/>
</SET>
<SET NR="03">
<ENTRY type="50" otherhattr="whatever"/>
<ENTRY type="50" otherhattr="whatever"/>
<ENTRY type="60" otherhattr="whatever"/>
</SET>
</GROUPD>
</Rootname>
我的结果必须是这样的:
1|b2|b456|01|10|1
1|b2|b456|02|10|2
1|b2|b456|02|20|1
1|c3|23|01|10|1
1|c3|23|02|10|1
1|c3|23|02|30|1
1|c3|23|02|50|1
1|d4|34|02|10|1
1|d4|34|03|50|2
1|d4|34|03|60|1
逻辑有点复杂,但我将描述: 有不同的组(GROUP)都属于FIRST元素。首先,我需要它们的属性“a”(FIRST和GROUP)和GROUP的属性“b”。第二步是我需要SET的数量(NR)。第三步也是最后一步是我需要ENTRY的“类型”和同一SET中具有相同类型的条目数量(ENTRY)。
现在有一个例外: GROUPB是一个特殊的,如果有一个属性“c”,我不需要“b”而是“c”。
我以为我可以用{GROUP-attribute“a”,SET-attribute“NR”和ENTRY-attribute“type”}来解决我的主要问题(同一组中具有相同类型的条目数)但我很沮丧,没有钥匙或任何东西。
我上次使用的XSL是这样的,问题是它在其他组和SETS中排除了ENTRIES:
<xsl:output method="text" encoding="ISO-8859-15" indent="no"/>
<xsl:template match="/">
<xsl:variable name="a" select="/*/FIRST/@a"/>
<xsl:if test="string($a) != ''">
<xsl:for-each select="/*/GROUPC[string(@a) != ''] | /*/GROUPB[string(@a) != '']| /*/GROUPD[string(@a) != '']">
<xsl:sort select="@a"/>
<xsl:variable name="out">
<xsl:apply-templates select=".">
<xsl:with-param name="a" select="$a"/>
</xsl:apply-templates>
</xsl:variable>
<xsl:value-of select="$out"/>
</xsl:for-each>
</xsl:if>
</xsl:template>
<xsl:template match="GROUPB">
<xsl:param name="a"/>
<xsl:variable name="begin">
<xsl:choose>
<xsl:when test="@c">
<xsl:value-of select="concat($a, '|', @a,'|',@c,'|')"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat($a, '|', @a,'|',@b,'|')"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="result">
<xsl:apply-templates select="SET/ENTRY">
<xsl:with-param name="begin" select="$begin"/>
</xsl:apply-templates>
</xsl:variable>
<xsl:value-of select="$result" />
</xsl:template>
<xsl:template match="GROUPC">
<xsl:param name="a"/>
<xsl:variable name="begin">
<xsl:value-of select="concat($a, '|', @a,'|',@b,'|')"/>
</xsl:variable>
<xsl:variable name="result">
<xsl:apply-templates select="SET/ENTRY">
<xsl:with-param name="begin" select="$begin"/>
</xsl:apply-templates>
</xsl:variable>
<xsl:value-of select="$result" />
</xsl:template>
<xsl:template match="GROUPD">
<xsl:param name="a"/>
<xsl:variable name="begin">
<xsl:value-of select="concat($a, '|', @a,'|',@b,'|')"/>
</xsl:variable>
<xsl:variable name="result">
<xsl:apply-templates select="SET/ENTRY">
<xsl:with-param name="begin" select="$begin"/>
</xsl:apply-templates>
</xsl:variable>
<xsl:value-of select="$result" />
</xsl:template>
<xsl:key name="art" match="ENTRY" use="@type"/>
<xsl:template match="SET">
<xsl:param name="begin"/>
<xsl:variable name="nummer">
<xsl:value-of select="@NR"/>
</xsl:variable>
<xsl:for-each select="ENTRY[generate-id() = generate-id(key('art',@type))]">
<xsl:value-of select="concat($begin, $nummer, '|', @type, '|', count(../ENTRY[@type=current()/@type]))" /><xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
最后一句话,可能有没有所需属性的GROUPS,SETS和ENTRIES,这些属性不应出现在结果中。
任何人都可以帮助我?
答案 0 :(得分:2)
我对你的描述感到有些困惑,我根本无法遵循你的代码。我想你想做这样的事情:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:key name="k" match="ENTRY" use="concat(generate-id(..), '|', @type)"/>
<xsl:template match="/Rootname">
<xsl:variable name="first-a" select="FIRST/@a" />
<xsl:for-each select="*/SET/ENTRY[count(. | key('k', concat(generate-id(..), '|', @type))[1]) = 1]">
<xsl:value-of select="$first-a"/>
<xsl:text>|</xsl:text>
<xsl:value-of select="../../@a"/>
<xsl:text>|</xsl:text>
<xsl:choose>
<xsl:when test="../../@c">
<xsl:value-of select="../../@c"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="../../@b"/>
</xsl:otherwise>
</xsl:choose>
<xsl:text>|</xsl:text>
<xsl:value-of select="../@NR"/>
<xsl:text>|</xsl:text>
<xsl:value-of select="@type"/>
<xsl:text>|</xsl:text>
<xsl:value-of select="count(key('k', concat(generate-id(..), '|', @type)))"/>
<xsl:text> </xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>