将 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('&#xA;',.)"/>
     <xsl:for-each select="key('kDateByVal',.)">
      <xsl:value-of select="concat('&#xA;','  ', ../description)"/>
     </xsl:for-each>
     <xsl:text>&#xA;</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 中的节点

如何将 sql 中的两个 xml 与出现的节点进行比较?

有没有办法使用 XSLT 基于 XML 中的元素复制 XML 节点 n 次?

有没有办法使用 XSLT 基于 XML 中的元素复制 XML 节点 n 次?