将 xml 中的节点与 xslt 进行比较
Posted
技术标签:
【中文标题】将 xml 中的节点与 xslt 进行比较【英文标题】:comparing nodes in xml with xslt 【发布时间】:2012-08-21 15:52:02 【问题描述】:我正在 xslt 的帮助下将 xml 数据转换为 html 页面。我想通过以下方式消除出现这样的重复数据。
xml 数据
<calendar>
<event>
<date>May 11</date>
<description>Mother's Day</description>
</event>
<event>
<date>May 12</date>
<description>Birthday</description>
</event>
<event>
<date>May 12</date>
<description>Board Meeting</description>
</event>
</calendar>
我的 xslt 代码
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2>Event Dates </h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>date</th>
<th>description</th>
</tr>
<xsl:for-each select="calendar/event">
<tr>
<td><xsl:value-of select="date"/></td>
<td><xsl:value-of select="description"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
我的输出
date description
May 11 Mother's Day
May 12 Birthday
May 12 Board Meeting
所需的输出。
date description
May 11
Mother's Day
May 12
Birthday
Board Meeting
请建议我修改 XSLT 代码。 提前致谢 。
【问题讨论】:
【参考方案1】:解决您的问题的唯一方法是所谓的“Muenchian Grouping”。请参阅 Muenchian Grouping - group within a node, not within the entire document 与您的问题几乎相同,只是名称而不是日期。
【讨论】:
【参考方案2】:这个短暂的转变:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:key name="kDateByVal" match="date" use="."/>
<xsl:template match="/">
<xsl:text>date description</xsl:text>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match=
"date[generate-id()=generate-id(key('kDateByVal',.)[1])]">
<xsl:value-of select="concat('
',.)"/>
<xsl:for-each select="key('kDateByVal',.)">
<xsl:value-of select="concat('
',' ', ../description)"/>
</xsl:for-each>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
使用经典的Muenchian grouping method 转换提供的 XML 文档:
<calendar>
<event>
<date>May 11</date>
<description>Mother's Day</description>
</event>
<event>
<date>May 12</date>
<description>Birthday</description>
</event>
<event>
<date>May 12</date>
<description>Board Meeting</description>
</event>
</calendar>
进入想要的、正确的结果:
date description
May 11
Mother's Day
May 12
Birthday
Board Meeting
【讨论】:
【参考方案3】:我找到了this 解决方案并应用于您的问题。 Jenni Tennison 写了一个nice and short explanation 的方法。
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="text" indent="yes"/>
<xsl:key name="distinct-date" match="/calendar/event/date" use="./text()"/>
<xsl:template match="calendar">
<xsl:text>date description
</xsl:text>
<xsl:for-each select="event/date[generate-id(.) = generate-id(key('distinct-date',.)[1])]">
<xsl:value-of select="./text()"/>
<xsl:text>
</xsl:text>
<xsl:apply-templates select="//event[date/text() = current()/text()]"/>
<xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
<xsl:template match="event">
<xsl:text> </xsl:text><xsl:value-of select="description/text()"/>
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
【讨论】:
以上是关于将 xml 中的节点与 xslt 进行比较的主要内容,如果未能解决你的问题,请参考以下文章
XSLT 2.0 for 循环一个与其他 XML 中的数据匹配的 XML 节点
如何获取具有相同名称的元素并根据 XSLT 中的子节点值对它们进行排序
将命名空间从 java 传递给 xslt,并使用 java 中的参数作为 xslt 中的节点