IBM®
跳转到主要内容
    中国 [选择]    使用条款
 
 
Select a scope: Search for:    
    首页    产品    服务与解决方案     支持与下载    个性化服务    
跳转到主要内容

developerWorks 中国  >  XML | Open source  >

使用 Google Mapplets 自定义 Google Maps 结果页面

使用 RSS、XSLT、PHP、KML 和 JavaScript 创建客户端和服务器端解决方案

developerWorks
前一页第 7 页,共 12 页后一页

文档选项

讨论

样例代码


对本教程的评价

帮助我们改进这些内容


创建 XSLT 样式表

现在,了解了将 XSLT 样式表应用到 XML 文档的方法后,可以创建样式表本身,将 Yahoo RSS 转换为 Google Mapplet 中的 KML。将对 Yahoo RSS 依次应用两个样式表。第一个样式表将其转换为更易管理的数据结构,第二个样式表将较简单的数据结构转换为最终的 KML。

使用 XSLT 简化数据结构

清单 10 中可以看出,Yahoo RSS 提要包含大量信息,结构有些复杂。另外,因为它来自外部组织,可能会随时改变数据的结构,因此,先将它转换为一个较简单的本地数据结构,可以不受这些改变影响。只要有一个中间 XSLT 样式表,可以将 Yahoo 的格式转换为本地格式,那么就可以设计最终的 KML,而不用考虑 Yahoo 的数据结构。创建中间样式表 yahoo-rss-to-simple-weather.xsl 的开始部分,如清单 23 所示。


清单 23. yahoo-rss-to-simple-weather.xsl
					
<xsl:stylesheet version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"
        xmlns:yweather="http://weather.yahooapis.com/ns/rss/1.0">

</xsl:stylesheet>

创建样式表的骨架部分,在 xmlns:xsl 行为 XSLT 指定 XML 的名称空间。geo 名称空间包含在 Yahoo RSS 提要中,yweather 名称空间也包含在 RSS 提要中。如果不定义名称空间,那么样式表不能识别那些名称空间中的元素。

接下来,添加一个模板,匹配 RSS 提要的 <channel> 元素,如清单 24 所示。


清单 24. 与 /rss/channel 匹配的 XSLT 模板
					
<xsl:template match="/rss/channel">
    <weather>

      <data-source>
    <link><xsl:value-of select="link"/></link>
    <icon><xsl:value-of select="image/url"/></icon>
      </data-source>     

      <xsl:apply-templates select="item/title"/>

      <xsl:apply-templates mode="coordinates"
               select="item"/>

      <xsl:apply-templates mode="condition-icon"
               select="item/description/img"/>

      <xsl:apply-templates mode="units"
               select="*[local-name()='units']"/>

      <xsl:apply-templates mode="condition"
               select="item/*[local-name()='condition']"/>

      <xsl:apply-templates mode="wind" 
               select="*[local-name()='wind']"/>

      <xsl:apply-templates mode="atmosphere" 
               select="*[local-name()='atmosphere']"/>

      <xsl:apply-templates mode="astronomy" 
               select="*[local-name()='astronomy']"/>

    </weather>
  </xsl:template>

该模板匹配 /rss/channel 元素,生成结果文档中的顶级 <weather> 元素。创建 <data-source> 元素,指定信息源。<data-source> 元素包含一个 <link> 元素,指定信息源的 URL,它的值来自源文档的 /rss/channel/link 元素(Yahoo Weather 的链接)。另外,还包含一个 <icon> 元素,将包含 Yahoo Weather 图标的 /rss/channel/image/url 元素的值作为它的值。然后,对源文档中的一些 Xpath 应用模板 — 首先是 /rss/channel/item/title 元素,然后是一些其他的数据元素。

其他模板应用的不同之处在于它们都指定 mode 属性。<xsl:apply-templates> 接收 select 属性,它指定将作为参数传递到模板的节点的 Xpath。另外,还包含一个可选的 mode 属性。mode 属性可以改变您对待 XSLT 模板的方式。模式没有为模板提供特定的 match 属性,而是允许把这些属性当作函数调用,与一个没有模式的模板相比,模式会更紧密地匹配一个模板应用。为使模板规范更简单,对 <xsl:apply-templates> 的每一个调用都指定传入模板的节点和模式。如果样式表中的每个模板都给定自己的模式,那么就不用指定必须匹配的对象 — 可以用星号(*)字符进行匹配。例如,清单 25 显示坐标模式的模板。


清单 25. “coordinates” 模式的模板
					
<xsl:template mode="coordinates" match="*">
    <coordinates>
      <latitude><xsl:value-of select="geo:lat"/></latitude>
      <longitude><xsl:value-of select="geo:long"/></longitude>
    </coordinates>      
  </xsl:template>

因为该模板指定了一个模式,用星号(*)表示与任何节点匹配,如果使用这个模板的模式调用 <xsl:apply-templates>,将与该模板进行匹配。这将其转换为一个更常规的函数调用,而不用重新指定要应用模板的 Xpath 表达式。现在将由模板的调用方使用正确的 Xpath 表达式(必须这样做)调用它。该方法简化了模板规范,将模板转换为函数。另外,可以创建两个模板,应用于相同类型的节点,但是生成不同的结果。例如,使用 <item> 元素调用 coordinates 模板,生成 <item> 的 <geo:lat> 和 <geo:long> 元素的 <coordinates> 元素。还可以定义其他的模板,使用 <item> 元素进行调用,从中提取不同的信息。

回顾 清单 24 中的 /rss/channel 模板,可以了解为什么需要去掉源文档中的 CDATA 元素标记。其中一个模板应用是 <xsl:apply-templates mode="condition-icon" select="item/description/img"/>。它使用 RSS 提要中的 <description> 的 <img> 标记调用 condition-icon 模板(使用这一模式的模板),因为要逐字输出模板,所以它最初包含在 CDATA 元素中。现在,去除 CDATA 标记后,该模板可以像获得源文档中其他 XML 元素一样获得 <img> 元素。

清单 24 中另外一个关注点是模板调用 <xsl:apply-templates mode="units" select="*[local-name()='units']"/>。它使用 units 模式调用模板,传入不包括名称空间前缀,本地名称为 units 的所有节点。这是一种从其他名称空间选择节点的方法。在 Yahoo RSS 提要中,units 元素实际是一个 <yweather:units> 元素。Xpath 函数 local-name() 返回没有名称空间的元素的名称,因此可以更容易进行处理。在 yweather 名称空间的 condition、atmosphere 和 astronomy 元素中重复使用该方法。

units、condition、astronomy 和 atmosphere 模式的模板看起来相同,在结果文档中创建一个元素,将源元素的属性复制到该元素中,像 units 模式的模板中一样(参阅清单 26)。


清单 26. units 模式的模板
					
<xsl:template mode="units" match="*">
    <units>
      <xsl:copy-of select="@*"/>
    </units>
  </xsl:template>

使用 <yweather:units> 元素调用该模板,生成结果文档中的 <units> 元素,它包含源元素的所有属性(参阅 附加源代码 获得其他相似的模板定义)。





回页首


将较简单的数据结构转换为 KML 覆盖层

第一个样式表将 Yahoo RSS 文档转换为可以控制的 tamer 数据结构。转换格式后,XML 就可以被转换为 KML 文档。为实现这一功能,创建名为 simple-weather-to-kml.xsl 的样式表,如清单 27 所示。


清单 27. simple-weather-to-kml.xsl
					
<xsl:stylesheet version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:template match="/weather">
    <kml xmlns="http://earth.google.com/kml/2.2">
      <Document>
    <name><xsl:value-of  select="title"/></name>
    <description>Local Weather from Yahoo!</description>
    <Placemark>
      <name>Local Weather</name>
      <description>
        CDATA_START
        <xsl:apply-templates mode="placemark-description"
                 select="."/>
        CDATA_END
      </description>
      <xsl:apply-templates select="coordinates"/>
    </Placemark>
      </Document>
    </kml>
  </xsl:template>

</xsl:stylesheet>

它定义与根级别的 <weather> 元素匹配的模板,生成一个根级别的 <kml> 元素。KML 是一个指定地理信息的 XML 专用语,也可以指定地理覆盖层信息,例如地图上显示的点、线、文本或 HTML。可以使用 KML 创建一个天气信息的覆盖层,在 Google Maps 结果页面显示。KML 文档包含 <Document> 元素,<Document> 元素中包含 <name> 元素、<description> 元素,并且,在本例中,还包含一个或多个 <Placemark> 元素,每个元素都可成为地图上可单击的标记。另外,文档中还包含覆盖在地图上的线,用来绘制填充或未填充的多边形。

可以看到在 XsltChainController 的构造函数调用中指定的 CDATA_START 和 CDATA_END。它们表示结果文档中的 CDATA 部分的开始和结束,但是,该样式表不包含 CDATA 标记本身,否则 XSLT 处理程序将忽略 CDATA 部分的 <xsl:apply-templates> 元素。CDATA 部分包含的 HTML 内容将显示在 Placemark 的弹出气球中。HTML 内容在使用 placemark-description 模式的模板中被创建,如清单 28 所示。


清单 28. “placemark-description” 模板
					
<xsl:template mode="placemark-description" match="*">
    <div>
      <div>
    <xsl:value-of select="condition/@text"/>, 
    <xsl:value-of select="condition/@temp"/> 
<xsl:value-of select="units/@temperature"/>
      </div>
      <div>
    Wind chill: <xsl:value-of select="wind/@chill"/> 
<xsl:value-of select="units/@temperature"/> <br/>
    Wind speed: 
    <xsl:value-of select="wind/@speed"/> 
    <xsl:value-of select="units/@speed"/>
      </div>
      <div>
    Humidity: <xsl:value-of select="atmosphere/@humidity"/>%
      </div>
      <div>
    Sunrise: <xsl:value-of select="astronomy/@sunrise"/> <br/>
    Sunset: <xsl:value-of select="astronomy/@sunset"/>
      </div>
    </div>
  </xsl:template>

该模板创建在地图标记的弹出气球中显示的 HTML,列出本地天气的所有信息。请注意,如何在 <xsl:value-of select="condition/@text"/> 中访问属性,这将输出 <condition> 子元素的 text 属性的值。该模板也使用 <units> 元素,其中包含每个计量的单位和它们的值。

清单 27 中的根级别的 <weather> 元素也对源文档(<xsl:apply-templates select="coordinates"/>)中的 <coordinates> 元素应用模板,生成 placemark 的坐标,如清单 29 所示。


清单 29. 与 <coordinates> 元素匹配的模板
					
<xsl:template match="coordinates">
    <Point>
      <coordinates>
    <xsl:value-of select="longitude"/>,<xsl:value-of select="latitude"/> 
      </coordinates>
    </Point>
  </xsl:template>

该模板生成结果文档中的 <Point> 元素,指定 placemark 的经度和纬度对 — 在 Google Map 中的位置。

要查看应用样式表的结果,在浏览器中访问 http://YOUR-SERVER/weather.php?zipcode=10010&units=f,查看页面源代码,类似于清单 30。


清单 30. 最终的 KML 覆盖层
					
<?xml version="1.0"?>
<kml xmlns="http://earth.google.com/kml/2.2">
  <Document>
    <name>Conditions for Maspeth, NY at 12:18 am EDT</name>
    <description>Local Weather from Yahoo!</description>
    <Placemark>
      <name>Local Weather</name>
      <description><![CDATA[
            <div>Mostly Cloudy,  57F</div>
            <div>
      Wind chill: 57F<br/>
      Wind speed: 7mph
            </div>
            <div>
      Humidity: 88%
            </div>
            <div>
      Sunrise: 6:57 am<br/>
      Sunset: 6:30 pm
            </div>
        ]]></description>
           <Point>
             <coordinates>-73.91,40.72</coordinates>
           </Point>
     </Placemark>
  </Document>
</kml>

请注意,这里的坐标远不及 Google Maps 中的坐标精确,意味着 placemark 实际上可能被放在地图中可见窗口的外面。为纠正这一问题,将地图适当缩小以确保 placemark 可见。





回页首


实际运行 KML

现在,整个 XSLT 链都可以发挥作用,可以在 Google mapplet 进行试验。单击 Reload 重新加载 Google 缓存中的 mapplet,选择 Server-side XSLT 单选按钮,移动或缩放地图。Placemark 将在地图上显示。单击它,将会呈现 XSLT 转换创建的 HTML 天气报告,如图 8 所示。


图 8. Google Maps 中显示的本地天气 Placemark 气球
Google Maps 中显示的本地天气 Placemark 气球




回页首



前一页第 7 页,共 12 页后一页
    关于 IBM 隐私条约 联系 IBM 使用条款