Xslt 从每个节点的XML中选择不同的子节点

Xslt 从每个节点的XML中选择不同的子节点,xslt,xslt-1.0,Xslt,Xslt 1.0,在花了几天时间尝试使用muenchian分组找到解决方案之后,我迫切需要一些帮助来找出转换XML的正确xslt代码,以便它能够为所有节目生成唯一的年份列表(最终导入Solr)。基本上,我需要对节点的唯一子节点进行分组,但不知何故,所有现有的解决方案都不适合我 以下是我的源XML: <?xml version="1.0" encoding="ISO-8859-1"?> <?xml-stylesheet type="text/xsl" href="http://localhost/

在花了几天时间尝试使用muenchian分组找到解决方案之后,我迫切需要一些帮助来找出转换XML的正确xslt代码,以便它能够为所有节目生成唯一的年份列表(最终导入Solr)。基本上,我需要对节点的唯一子节点进行分组,但不知何故,所有现有的解决方案都不适合我

以下是我的源XML:

<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="http://localhost/default.xsl" ?>
<DIRECTORY>
    <SHOWS>
        <SHOW>
            <TITLE>Child's play</TITLE>
            <EVENTS>
                <EVENT>
                    <YEAR>2014</YEAR>
                    <TITLE>Gala day</TITLE>
                </EVENT>
                <EVENT>
                    <YEAR>2014</YEAR>
                    <TITLE>Gala night</TITLE>
                </EVENT>
                <EVENT>
                    <YEAR>2015</YEAR>
                    <TITLE>Gala night</TITLE>
                </EVENT>
            </EVENTS>
        </SHOW>
    </SHOWS>
</DIRECTORY>

儿童游戏
2014
节日
2014
狂欢之夜
2015
狂欢之夜
以下是所需的输出:

<?xml version="1.0"?>
<add>
  <doc>
    <field name="show_title">Child's play</field>
    <field name="show_year">2014</field>
    <field name="show_year">2015</field>
  </doc>
</add>

儿童游戏
2014
2015
这里是我的XSLT,它不起作用,它基于关于堆栈溢出的各种答案

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" omit-xml-declaration="no"/>

    <xsl:key name="show_key"
             match="TITLE"
             use="TITLE"/>

    <xsl:key name="show_years_key"
             match="TITLE"
             use="concat(TITLE, ' ',
                     EVENTS/EVENT/YEAR)"/>

    <xsl:template match="/">
        <add>
            <xsl:for-each select="/DIRECTORY/SHOWS/SHOW">
                <doc>
                    <xsl:call-template name="show_info"/>
                </doc>
            </xsl:for-each>
        </add>
    </xsl:template>

    <xsl:template name="show_info">
        <field name="show_title">
            <xsl:value-of select="TITLE"/>
        </field>
        <xsl:variable
                name="show_events"
                select="key('show_key', TITLE)"/>
        <xsl:for-each
                select="$show_events[generate-id() =
                             generate-id(
                               key('show_years_key',
                                   concat(TITLE,
                                          ' ',
                                          EVENTS/EVENT/YEAR))[1])]">
            <field name="show_years">
                <xsl:value-of select="EVENTS/EVENT/YEAR"/>
            </field>
        </xsl:for-each>

    </xsl:template>
</xsl:stylesheet>


虽然我真的很感谢任何帮助,以获得一个工作的解决方案,我也可以使用一些指针,为什么我的解决方案不工作时,它应该。我故意让这个最小的示例稍微复杂一些,因为我怀疑我的xslt组织可能会使事情变得更复杂,但总体解决方案工作得相当好,即使有多个不同的模板。

分组键需要与您试图分组的元素(即
元素)匹配。我在遵循您的
调用模板
逻辑时遇到了一些问题,我会更像这样处理:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" omit-xml-declaration="no"/>

    <xsl:key name="show_years_key"
             match="YEAR"
             use="concat(ancestor::SHOW[1]/TITLE, ' ', .)"/>

    <xsl:template match="/">
        <add>
            <xsl:apply-templates select="/DIRECTORY/SHOWS/SHOW" />
        </add>
    </xsl:template>

    <xsl:template match="SHOW">
        <doc>
            <field name="show_title">
                <xsl:value-of select="TITLE"/>
            </field>
            <!-- current() here is the SHOW element this template applies to -->
            <xsl:for-each select="EVENTS/EVENT/YEAR[generate-id() = generate-id(
                    key('show_years_key', concat(current()/TITLE, ' ', .))[1])]">
                <field name="show_years">
                    <xsl:value-of select="." />
                </field>
            </xsl:for-each>
        </doc>
    </xsl:template>
</xsl:stylesheet>


重要的一点是,您是根据
SHOW
标题对
元素进行分组,而不是根据
元素对
元素进行分组。

哇,这与预期一样有效-非常感谢您快速准确的回答!!之所以使用调用模板,是因为有许多不同的元素需要处理,我们使用这种方法保持了文件的结构。总的来说这让人很困惑,所以非常感谢你的帮助!