用XSL对XML进行分组
我有点被分组所困扰。我有以下XML代码:用XSL对XML进行分组,xml,xslt-1.0,Xml,Xslt 1.0,我有点被分组所困扰。我有以下XML代码: <?xml version="1.0" encoding="UTF-8"?> <isif_data> <date>29.05. <event-date> <type>type1</type> <Time Timesort="1845">18.45<
<?xml version="1.0" encoding="UTF-8"?>
<isif_data>
<date>29.05.
<event-date>
<type>type1</type>
<Time Timesort="1845">18.45</Time>
<title>event1</title>
<cell/>
<place>abc</place>
</event-date>
<event-date>
<type>type1</type>
<Time Timesort="0900">9</Time>
<title>event2</title>
<cell/>
<place>abd</place>
</event-date>
<event-date>
<type>type2</type>
<Time Timesort="1930">19.30</Time>
<title>event3</title>
<cell/>
<place>abe</place>
</event-date>
<event-date>
<type>type2</type>
<Time Timesort="1900">19</Time>
<title>event4</title>
<cell/>
<place>abf</place>
</event-date>
</date>
<date>30.05.
<event-date>
<type>type1</type>
<Time Timesort="1845">18.45</Time>
<title>event5</title>
<cell/>
<place>abg</place>
</event-date>
<event-date>
<type>type2</type>
<Time Timesort="0900">9</Time>
<title>event6</title>
<cell/>
<place>abh</place>
</event-date>
<event-date>
<type>type1 </type>
<Time Timesort="1500">15</Time>
<title>event7</title>
<cell/>
<place>abi</place>
</event-date>
<event-date>
<type>type2</type>
<Time Timesort="1700">17</Time>
<title>event8</title>
<cell/>
<place>abj</place>
</event-date>
</date>
</isif_data>
29.05.
类型1
18.45
事件1
abc
类型1
9
事件2
阿布德
类型2
19.30
事件3
阿贝
类型2
19
事件4
abf
30.05.
类型1
18.45
事件5
abg
类型2
9
事件6
abh
类型1
15
事件7
阿比
类型2
17
事件8
abj
现在我需要生成的XML如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<isif_data>
<date>29.05.</date>
<type>type1</type>
<Time>9</Time>
<title>event2</title>
<cell/>
<place>abd</place>
<Time>18.45</Time>
<title>event1</title>
<cell/>
<place>abc</place>
<type>type2</type>
<Time>19</Time>
<title>event4</title>
<cell/>
<place>abf</place>
<Time>19.30</Time>
<title>event3</title>
<cell/>
<place>abe</place>
<date>30.05.</date>
<type>type1</type>
<Time>15</Time>
<title>event7</title>
<cell/>
<place>abi</place>
<Time>18.45</Time>
<title>event5</title>
<cell/>
<place>abg</place>
<type>type2</type>
<Time>9</Time>
<title>event6</title>
<cell/>
<place>abh</place>
<Time>17</Time>
<title>event8</title>
<cell/>
<place>abj</place>
</isif_data>
29.05.
类型1
9
事件2
阿布德
18.45
事件1
abc
类型2
19
事件4
abf
19.30
事件3
阿贝
30.05.
类型1
15
事件7
阿比
18.45
事件5
abg
类型2
9
事件6
abh
17
事件8
abj
我用明钦的方法试过,但我从来没有让它像我想要的那样工作过。这里有谁知道如何让它工作吗?我需要使用XSL1.0版。如果你需要更多的信息就告诉我。提前感谢:-)
编辑:我尝试了以下XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="UTF-8" indent="yes" />
<xsl:key name="type" match="event-date" use="type" />
<xsl:template match="isif_data">
<xsl:element name="isif_data">
<xsl:for-each select="date">
<xsl:element name="date"><xsl:value-of select="date"/></xsl:element>
<xsl:element name="cell"/>
<xsl:for-each select="event-date[count(. | key('type', type)[1]) = 1]">
<xsl:sort select="time/@Timesort" />
<xsl:call-template name="type" />
<xsl:for-each select="key('type', type)">
<xsl:call-template name="time" />
<xsl:call-template name="title" />
<xsl:call-template name="place" />
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
如果你需要模板,我也可以提供。我不确定是否需要它们
是否有可能从列表中为每个日期标记创建一个组
原始代码
这:
将按类型对所有事件日期进行分组,而不考虑日期。由于要在每个日期内按类型对事件进行分组,因此需要在键中同时使用日期和类型:
<xsl:key name="type" match="event-date" use="concat (../., '|', type)" />
如果我假设带空格或不带空格的类型应分组为一个,那么确实需要进行键控,因为需要对空格进行规范化。然后它将看起来像:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="types" match="event-date"
use="concat(normalize-space(../text()), normalize-space(type))"/>
<xsl:template match="event-date">
<xsl:variable name="thisType" select="normalize-space(type)"/>
<xsl:variable name="thisSet"
select="key('types', concat(normalize-space(../text()), $thisType))"/>
<xsl:if test="count(. | $thisSet[1]) = 1">
<type><xsl:value-of select="$thisType"/>
<xsl:for-each select="$thisSet">
<xsl:apply-templates select="node()"/>
</xsl:for-each>
</type>
</xsl:if>
</xsl:template>
<xsl:template match="type"/>
<xsl:template match="node()">
<xsl:copy>
<xsl:copy-of select="@*" />
<xsl:apply-templates select="node()" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
如果没有空格等,你就不需要整个键控。然后它看起来像:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template
match="event-date[not(type = preceding-sibling::*/type)]">
<type><xsl:value-of select="type"/>
<xsl:apply-templates select="../*[type=current()/type]/node()"/>
</type>
</xsl:template>
<xsl:template match="event-date | type"/>
<xsl:template match="node()">
<xsl:copy>
<xsl:copy-of select="@*" />
<xsl:apply-templates select="node()" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
更新了我的原始帖子。我强烈建议你去掉混合内容元素。节点要么包含文本,要么包含子元素。不是两者都有。混合内容会给你自己带来不必要的麻烦。你读过吗:?好的,我更新了我原来的端口。谢谢@michael.hor257k提供信息。现在分组工作了。但不完全正确。是否有可能根据原始代码为每个日期标记创建一个组?谢谢@Tomalak。发布错误结果是我的错。实际上,我使用xsl来转换您建议的方式。日期标记中有一个属性,它为我提供了所需的文本。因此节点中的文本是非常不必要的。对不起,木琴分组不是关于空格等-而是关于性能。您使用谓词的选择是“非常低效的”(引用上述文章)。对不起,我不知道这个问题涉及性能问题。我想说的是,在这种情况下,绩效在很大程度上取决于日期和日期内事件的数量。我不确定明钦族的组合是否总能带来更好的表现。谢谢!我不知道为什么我以前没有看到这个。你是最棒的。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template
match="event-date[not(type = preceding-sibling::*/type)]">
<type><xsl:value-of select="type"/>
<xsl:apply-templates select="../*[type=current()/type]/node()"/>
</type>
</xsl:template>
<xsl:template match="event-date | type"/>
<xsl:template match="node()">
<xsl:copy>
<xsl:copy-of select="@*" />
<xsl:apply-templates select="node()" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>