Xslt 从每个节点的XML中选择不同的子节点
在花了几天时间尝试使用muenchian分组找到解决方案之后,我迫切需要一些帮助来找出转换XML的正确xslt代码,以便它能够为所有节目生成唯一的年份列表(最终导入Solr)。基本上,我需要对节点的唯一子节点进行分组,但不知何故,所有现有的解决方案都不适合我 以下是我的源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/
<?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
的标题对年
元素进行分组,而不是根据年
元素对年
元素进行分组。哇,这与预期一样有效-非常感谢您快速准确的回答!!之所以使用调用模板,是因为有许多不同的元素需要处理,我们使用这种方法保持了文件的结构。总的来说这让人很困惑,所以非常感谢你的帮助!