如何使用XML和XSL创建锚链接?

时间:2011-05-26 20:35:34

标签: xml xslt

嘿伙计们,我想要制作的是动物园的迷你时间表。

下面是功能的ms paint模型。我想要的是横向排列的时间列表,当您点击一个时,页面会向下移动到该时间段并显示其详细信息。

与HTML中的锚标签完全相同,我的数据以XML格式存储。

enter image description here

所以这是我的xml数据:

<zoo>
<animal name="Lion">
<feeding-time>11:00</feeding-time>
</animal>
<animal name="Penguin">
<feeding-time>14:00</feeding-time>
</animal>
<animal name="Elephant">
<feeding-time>9:00</feeding-time>
</animal>
<animal name="Tortoise">
<feeding-time>11:00</feeding-time>
</animal>
<animal name="Ape">
<feeding-time>16:00</feeding-time>
</animal>
<animal name="Hippo">
<feeding-time>14:00</feeding-time>
</animal>
<animal name="Rattle Snake">
<feeding-time>9:00</feeding-time>
</animal>
<animal name="Flamingo">
<feeding-time>15:00</feeding-time>
</animal>
</zoo>

我的XSL页面非常平淡:

<xsl:template match="/">
<html>
<head>
  <title>Real Estate Listings</title>
  <link href="style.css" rel="stylesheet" type="text/css" />
</head>
   <body>

   </body>
</html>
</xsl:template>

</xsl:stylesheet>

我知道我需要使用轴和/或Meunchian分组来使用定位器路径 - 我已经研究了几个小时,我仍然不知道最新情况。

我知道我需要使用generate-id函数,并且使用key函数很好但又一次,我不知道如何实现它 - iv花了几个小时在谷歌试图计算出这些东西。< / p>

任何帮助都会很有用。

2 个答案:

答案 0 :(得分:2)

此转化

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:key name="kTimeByVal" match="feeding-time"
  use="."/>

 <xsl:key name="kAnimalByTime" match="@name"
  use="../feeding-time"/>

 <xsl:template match="/">
  <xsl:apply-templates/>

  <xsl:apply-templates mode="group"/>
 </xsl:template>

 <xsl:template match=
  "feeding-time[generate-id()
               =
                generate-id(key('kTimeByVal',.)[1])
               ]
  ">

  <a href="#{generate-id()}">
  <xsl:value-of select="."/>
  </a>
  <xsl:text> </xsl:text>
 </xsl:template>

 <xsl:template mode="group" match=
  "feeding-time[generate-id()
               =
                generate-id(key('kTimeByVal',.)[1])
               ]
  ">

  <br /><p id="{generate-id()}"><xsl:text/>

  <b><xsl:value-of select="."/> Feeding Time for:</b></p>

  <xsl:apply-templates select="key('kAnimalByTime', .)"/>
 </xsl:template>

 <xsl:template match="@name">
  <br /><xsl:value-of select="."/>
 </xsl:template>

 <xsl:template match="text()"/>
 <xsl:template mode="group" match="text()"/>
</xsl:stylesheet>

应用于提供的XML文档

<zoo>
    <animal name="Lion">
        <feeding-time>11:00</feeding-time>
    </animal>
    <animal name="Penguin">
        <feeding-time>14:00</feeding-time>
    </animal>
    <animal name="Elephant">
        <feeding-time>9:00</feeding-time>
    </animal>
    <animal name="Tortoise">
        <feeding-time>11:00</feeding-time>
    </animal>
    <animal name="Ape">
        <feeding-time>16:00</feeding-time>
    </animal>
    <animal name="Hippo">
        <feeding-time>14:00</feeding-time>
    </animal>
    <animal name="Rattle Snake">
        <feeding-time>9:00</feeding-time>
    </animal>
    <animal name="Flamingo">
        <feeding-time>15:00</feeding-time>
    </animal>
</zoo>

产生完全想要的结果:

<a href="#d0e5">11:00</a> 
<a href="#d0e11">14:00</a> 
<a href="#d0e17">9:00</a> 
<a href="#d0e29">16:00</a> 
<a href="#d0e47">15:00</a> 
<br/>
<p id="d0e5">
   <b>11:00 Feeding Time for:</b>
</p>
<br/>Lion<br/>Tortoise<br/>
<p id="d0e11">
   <b>14:00 Feeding Time for:</b>
</p>
<br/>Penguin<br/>Hippo<br/>
<p id="d0e17">
   <b>9:00 Feeding Time for:</b>
</p>
<br/>Elephant<br/>Rattle Snake<br/>
<p id="d0e29">
   <b>16:00 Feeding Time for:</b>
</p>
<br/>Ape<br/>
<p id="d0e47">
   <b>15:00 Feeding Time for:</b>
</p>
<br/>Flamingo

它在浏览器中完全按照需要显示,并且具有所需的(链接点击)行为:

11:00 14:00 9:00 16:00 15:00

    11:00喂食时间:


狮子

    14:00喂食时间:


企鹅
河马

    9:00喂食时间:


大象嘎嘎蛇

    16:00喂食时间:



    15:00喂食时间:


火烈鸟

解释:Muenchian分组,使用generate-id()生成唯一ID以用作锚点,使用键。

答案 1 :(得分:0)

Muenchian分组使用在XSLT表的根级别定义的键,它允许key函数返回满足给定条件的所有元素的列表,然后从该列表中选择第一个项目。例如:

<xsl:key name="feedingTime" match="*" use="feeding-time" />

这样,您就可以致电key('feedingTime','11:00')以获取feeding-time元素值为11:00的所有元素的列表。

您可以在具有generate-id()功能的模板中使用此功能,该功能会返回每个ID的唯一值。您可以通过比较当前正在处理的元素的id与具有相同feeding-time值的所有元素的列表中第一个元素的id来实现此目的。像这样:

<xsl:if test="generate-id(feeding-time) = generate-id(key('feeding-time',feeding-time)[1])">
  <!-- generate output -->
</xsl:if>

或者,您可以在模板匹配中使用相同的条件,并使用相同的密钥以当前的进纸时间迭代animal节点列表:

<xsl:template match="animal[generate-id() = generate-id(key('feedingTime',feeding-time)[1])]">
  <!-- output a heading here, current node is first animal node with each feeding-time -->
  <xsl:for-each select="key('feedingTime',feeding-time)">
    <!-- output each animal here -->
  </xsl:for-each>
</xsl:template>

如果你这样做,你需要包含一个这样的空模板:<xsl:template match="animal" />来处理剩余的animal元素,丢弃它们;你已经在上面模板的for-each循环中处理了它们。

您可以使用模板模式分别处理链接和下面的内容列表,如下所示:

<xsl:key name="feedingTime" match="*" use="feeding-time" />

<xsl:template match="zoo">
  <xsl:apply-templates mode="links" />
  <xsl:apply-templates mode="content" />
</xsl:template>

<xsl:template match="animal[generate-id() = generate-id(key('feedingTime',feeding-time)[1])]" mode="links">
  <a href="#time_{feeding-time}">
    <xsl:value-of select="feeding-time" />
  </a>
</xsl:template>

<xsl:template match="animal[generate-id() = generate-id(key('feedingTime',feeding-time)[1])]" mode="content">
  <p id="time_{feeding-time}">
    <xsl:value-of select="concat(feeding-time,' Feeding time for:')" />
  </p>
  <ul>
    <xsl:for-each select="key('feedingTime',feeding-time)">
      <li>
        <xsl:value-of select="@name" />
      </li>
    </xsl:for-each>
  </ul>
</xsl:template>

<xsl:template match="animal" mode="links" />
<xsl:template match="animal" mode="content" />

底部的两个模板用于处理前一个未处理的所有animal个元素(即每个馈送时间的第二个和后一个animal元素)。我没有在这里处理格式化,但希望它应该展示可以帮助你的技术。