Board logo

标题: 使用 XForms 创建动态 Web 搜索(1) [打印本页]

作者: look_w    时间: 2018-7-20 10:23     标题: 使用 XForms 创建动态 Web 搜索(1)

简介什么不能使用 Google?自从首次推出基于 SOAP 的接口以来,Google 便成为了基于 XML 的 API 典范,使应用程序操作 Google 数据成为了可能。可惜的是,2006 年 12 月 5 日 Google 中止了其 SOAP 接口并停止发放新的 token。而这些都是运行这些应用程序所必需的。Google 公司取而代之的是 Ajax 版本的 API。该版本完美地把 Google 数据集成到了一个 Web 页面中,但是并不能被其他程序使用。遗憾的是,这就意味着在一般情况下,我们不能像以前那样在此类应用程序中使用 Google 数据了。

本文演示了如何创建一个足够灵活的接口,使用这个接口能够查看若干个基于 XML 的 API 产生的结果。方法是实现一个搜索引擎客户机供用户在其中选择搜索数据的引擎并自动接收合适的条目字段和数据。此外,表单加载了“后台中”的数据,也就是说,在页面上显示结果不需要完全重新加载。
本例中使用的 API 包括 Yahoo! 和 Teoma 搜索引擎,但文章传达的思想适用于任何能返回 XML 的 API。这两个搜索引擎都有一个基于 REST 的接口,也就是说提供给它们一个 URL 和所有参数,它们将返回带有结果的 XML。
XForms 实现对内容的动态更改无需通过将 XForms 可视化表示(visual presentation)链接到 XML 数据结构来重新提交来自服务器的页面。当 XML 数据结构发生变化时,可视化表示将被重新计算并作出相应变化而无需重新加载页面。更改隐藏在表示下面的 XML 数据可以通过很多种方法实现。比如说,本例中的表单包含了一个下拉菜单,它列出了可用的搜索引擎。用户只能填写与活动引擎关联的字段。基本引擎表单如图 1 所示。
图 1. 尚未进行任何搜索的搜索表单先决条件在开始创建表单之前,需要准备好如下软件:
创建 XForms 数据结构为支持本例的搜索引擎,表单使用了三个实例来实现数据结构。每个实例都有惟一的名称,以便稍后检索。其中两个元素是空容器,用作搜索引擎返回的 XML 的加载点。另一个实例包含了搜索的输入数据:Yahoo 搜索的应用程序 ID、查询字符串(定义为 q)、两个 Yahoo 特有的字段(site 和 results)。这些数据位于 box 实例中,如清单 1 所示。
清单 1. XML 数据结构,第 1 部分
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html
   xmlns="http://www.w3.org/1999/xhtml"
   xmlns:y="urn:yahoo:srch"
   xmlns:xforms="http://www.w3.org/2002/xforms"
   xmlns:ev="http://www.w3.org/2001/xml-events"
>

  <head>
    <title>Using XForms To Build A Dynamic Search Engine</title>
    <xforms:model id="model_dynsrch">

      <xforms:instance id="box">
        <search xmlns="">
          <engine>Yahoo</engine>
          <appid>your_yahoo_app_id</appid>
          <q>horse</q>
          <site></site>
          <results></results>
          <submitTeoma/>
          <submitYahoo/>
        </search>
      </xforms:instance>

      <xforms:bind nodeset="instance('box')/site"
               relevant="instance('box')/engine = 'Yahoo'" />
      <xforms:bind nodeset="instance('box')/results"
               relevant="instance('box')/engine = 'Yahoo'" />
      <xforms:bind nodeset="instance('box')/submitYahoo"
               relevant="instance('box')/engine = 'Yahoo'" />
      <xforms:bind nodeset="instance('box')/submitTeoma"
               relevant="instance('box')/engine = 'Teoma'" />
      
      <xforms:instance id="yahoo">
        <ResultSet xmlns="urn:yahoo:srch"/>
      </xforms:instance>

      <xforms:instance id="teoma">
        <SEARCHRESULTS xmlns=""/>
      </xforms:instance>




很显然,这个 XHTML 的独到之处应该就是在 HTML 标记中使用了 xmlns:y="urn:yahoo:srch"。这与 Yahoo 搜索的数据实例有关。Yahoo 使用 xmlns="urn:yahoo:srch" 返回搜索数据。因为 Yahoo 只识别这个特定的名称空间,所以我们在引用其数据时也必须使用该名称空间;否则,将显示为“不可见(invisible)”。后面我们将看到所有引用 Yahoo 搜索结果的 XForms 代码都使用了在头部指定的 y:。(记住,前缀是什么无关紧要;真正起作用的是名称空间。)此处的实例定义中,为搜索结果的 XML 数据节点了调用了名称空间。
box 实例同时包含了基本信息(2)和站点特定的信息(appid、site 和 results)。我们将根据引擎元素的值控制站点特定信息的外观。比方说,绑定元素指定了只有当引擎为“Yahoo”时,site 和 results 元素才会“关联(relevant)”在一起。稍后,当我们创建真正的表单时,会发现尽管这些项都在页面上,但是只有关联项才会在页面上显示出来。使用 submitYahoo 和 submitTeoma 元素可以类似地控制 Submit 按钮的可见性。
还有一个相当细微的地方需要注意,稍不注意便有可能影响到其后的设计。如 所示,三个实例的名称分别为 box、yahoo 和 teoma。请记住,这些名称都是特定于这些实例数据结构的。并不能把它们当做标识符随意使用。在本例后面的 switch/case/toggle 机制中重用 teoma 和 yahoo 这两个 ID 会是个不小的诱惑,但是由于它们的名称都引用了实例数据所以并不能正常运行。
submission 的定义 显示了 XForm 其余的数据结构。剩下的两项为 submission 元素。本例使用了两个 submission 元素,分别对应于不同的搜索。对于这些 submission 元素,有三点需要注意。这三点各自发挥自己的作用,确保“后台搜索”顺利进行而不用重新加载页面。每个 submission 元素都指定了一个 replace 和 instance 关键字。请注意:每个 submission 元素都是使用  中选定的名称来引用实例的。这个机制指定:从该 submission 元素返回的数据将替代指定的实例节点中的 XML 数据。这样便可以清除搜索或者用新搜索结果替代原搜索。请注意,两个 submission 元素都使用了 ref="instance('box')"。这将指示 submission 动作使用 box 实例的 XML 作为输入,并且由于此引擎的实质在于使用户能搜索不同的引擎而无需分别键入相同的搜索字符串,因此两个 submission 元素都引用了相同的输入数据。Yahoo 特定信息同样也传递给了 Teoma 搜索引擎,但是会被 Teoma PHP 代理忽略。
清单 2. XML 数据结构,第 2 部分
1
2
3
4
5
6
7
8
9
10
11
12
    <xforms:submission id="submit_teoma" separator="&"

                       action="teomaproxy.php" method="get"
                       ref="instance('box')"
                       replace="instance" instance="teoma"/>
     
    <xforms:submission id="submit_yahoo" separator="&"
                       action="yahooproxy.php" method="get"
                       ref="instance('box')"
                       replace="instance" instance="yahoo"/>
  </xforms:model>
</head>




两个 submission 定义中都使用了 PHP 脚本:<engine>proxy.php。这两个脚本在本质上是相同的,只是基本 URL 和包含的数据有所不同。这些 PHP 脚本使用 cURL 扩展名分别在两个引擎中检索 XML 数据,并将数据返回给 XForms。这样,数据处理实际上就是在 XForms 实现中进行的。清单 3 显示了 Yahoo PHP 脚本。前面已经说过,Teoma 脚本与它几乎是相同的。
清单 3. Yahoo 代理脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php

$appid = urlencode($_GET['appid']);
if($_GET['site'] != '')
    $q = urlencode($_GET['q']." site:".$_GET['site']);
else
    $q = urlencode($_GET['q']);
$results = urlencode($_GET['results']);

$url =
"http://api.search.yahoo.com/WebSearchService/V1/webSearch?appid=$appid&query=$q&results=
$results";

$curl = curl_init();

curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HEADER, false);

$str = curl_exec($curl);
curl_close($curl);

echo $str;

?>




由于使用 GET 作为 submission 的方法,PHP 脚本就像从传统 Web 表单中那样接收此信息。一旦输入了用于搜索的适当 URL,cURL 将提交该信息并返回结果。
同样也可以使用 POST 方法,但必须确保正确地处理 URL 编码数据。当提交的对象是搜索引擎 API 时,也可以直接向表单提交 XML。例如,当 MSN Live Search API 处理 SOAP 事务时。清单 4 显示了如何处理用 POST 提交的信息。
清单 4. 使用 POST 的 Yahoo 代理 PHP 脚本
1
2
3
4
5
6
7
8
<?php

$xml = $HTTP_RAW_POST_DATA;
$doc = new DomDocument('1.0');
$doc->loadXML($xml);
$appid = $doc->getElementsByTagName("appid")->item(0)->nodeValue;
$query = $doc->getElementsByTagName("q")->item(0)->nodeValue;
...




接下来我们回到表单本身




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0