在尝试使用muenchian分组找到解决方案花了几天之后,我迫切需要一些帮助来找出用于转换我的XML的正确xslt代码,以便它将为所有节目生成一个独特的年份列表(是最终导入Solr)。基本上我需要对节点的独特孙子进行分组,但不知何故SO上的所有现有解决方案对我都不起作用。
这是我的源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>
这是所需的输出:
<?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>
这是我的XSLT不起作用,并基于Stack Overflow的各种答案
<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组织可能会使事情变得更复杂,所以我将最小的例子留下了更复杂的一点,但整体解决方案效果很好,即使有多个不同的模板也是如此。
答案 0 :(得分:0)
分组键需要匹配您尝试分组的元素(即YEAR
元素)。我跟你的call-template
逻辑有点麻烦,我更接近这个:
<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>
重要的一点是,您要将YEAR
元素按其TITLE
的{{1}}分组,而不是SHOW
元素SHOW
元素。它们包含。