未知命名元素上的键
key on unknown named Element
我有一个 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。所以首先我需要它们(FIRST 和 GROUP)的属性 "a" 和 GROUP 的属性 "b"。第二步是我需要 SET 的编号(NR)。第三步也是最后一步是我需要 ENTRY 的 "type" 和同一 SET 中相同类型的条目 (ENTRY) 的数量。
现在有一个例外:
GROUPB比较特殊,如果有属性"c",我不需要"b"但是"c".
我想我可以通过带有{GROUP-attribute "a"、SET-attribute "NR" 和 ENTRY 的键来解决我的主要问题(同一组中相同类型的条目数) -attribute "type"} 但我很沮丧,没有得到任何钥匙或任何东西。
我最后一个工作的 XSL 是这个,问题是它在其他组和集合中整理条目:
<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 没有一个想要的属性,这些不应该出现在结果中。
有人可以帮助我吗?
我对你的描述有点困惑,我根本无法理解你的代码。我认为你想做这样的事情:
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>
我有一个 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。所以首先我需要它们(FIRST 和 GROUP)的属性 "a" 和 GROUP 的属性 "b"。第二步是我需要 SET 的编号(NR)。第三步也是最后一步是我需要 ENTRY 的 "type" 和同一 SET 中相同类型的条目 (ENTRY) 的数量。
现在有一个例外: GROUPB比较特殊,如果有属性"c",我不需要"b"但是"c".
我想我可以通过带有{GROUP-attribute "a"、SET-attribute "NR" 和 ENTRY 的键来解决我的主要问题(同一组中相同类型的条目数) -attribute "type"} 但我很沮丧,没有得到任何钥匙或任何东西。
我最后一个工作的 XSL 是这个,问题是它在其他组和集合中整理条目:
<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 没有一个想要的属性,这些不应该出现在结果中。
有人可以帮助我吗?
我对你的描述有点困惑,我根本无法理解你的代码。我认为你想做这样的事情:
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>