Skip to main content

By clicking Submit, you agree to the developerWorks terms of use.

The first time you sign into developerWorks, a profile is created for you. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

All information submitted is secure.

  • Close [x]

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerworks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

By clicking Submit, you agree to the developerWorks terms of use.

All information submitted is secure.

  • Close [x]

Use XForms to create a dynamic Web search

Discover the flexibility of XForms

Stony Yakovac (syakovac@gmail.com), Software engineer, Freelance
Stony Yakovac is an engineer and freelance author living in Lava Hot Springs, Idaho. He works on a wide variety of projects, including software and digital hardware designs.

Summary:  The tight integration XForms has with XML makes it perfect for viewing the results of XML-based APIs. At the same time, it's powerful enough to create a dynamic interface that can react to changing conditions. This article explains how to use these capabilities by showing you how to create a dynamic search engine client that provides different options and shows different data depending on the search engine chosen.

Date:  06 Mar 2007
Level:  Intermediate
Also available in:   Chinese  Japanese

Activity:  8497 views
Comments:  

Introduction

Why not Google?

Google has been the poster child for XML-based APIs since it first launched its SOAP-based interface, enabling applications to pull Google data and do just about anything with it. Unfortunately, on December 5, 2006, Google pulled the plug on its SOAP interface and stopped issuing new tokens, which are required to run these applications. The company replaced the API with an Ajax-based version that's perfect for integrating Google data into a Web page, but can't be used for anything else. Unfortunately, that means that as a general rule, you can no longer use Google data in this type of application.

This article demonstrates the creation of an interface flexible enough to view the results of multiple XML-based APIs by implementing a search engine client in which the user selects the engine the data comes from and automatically receives the appropriate entry fields and data. In addition, the form loads the data "in the background," so to speak, displaying the results on the page without requiring a full reload.

In this case, the APIs involved are those of search engines Yahoo! and Teoma, but the concepts covered in this article apply to any situation in which you have an API that returns XML. Both search engines have a REST-based interface, which means you feed them a URL with all of your parameters and they give you back XML with the results.

XForms implements dynamic changes to the content without re-submitting the page from the server by linking the XForms visual presentation to an XML data structure. When the XML data structure is changed, the visual presentation is re-calculated and changes without having to reload the page. There are many methods of changing the XML data behind the presentation. For example, this form will include a pulldown menu that lists the available search engines. The user will only be able to fill out fields that are relevant to the active engine. The basic engine form is shown in Figure 1.


Figure 1. The search form before any searches
The search form before any searches

Prerequisites

Before you jump in and start creating the form, you'll need some software:

  • A browser capable of displaying XForms, such as Firefox with the XForms extension. (See the Resources for a download link.)
  • A Web server with PHP enabled. Specifically for this example, PHP must have the cURL extensions for accessing the search engines (see Resources for a download link).
  • An application ID for Yahoo search. Teoma does not require an ID. This ID is available on the Yahoo Web site (see Resources).

Creating the XForms data structure

The form uses three instances to implement the data structures that enable this search engine. Each instance is uniquely named so that it can be retrieved later. Two of the elements are empty containers to be used as loading points for the returned XML from the search engines. The third instance contains the data used as input to the search, the Yahoo application ID for Yahoo searches, the query string, defined as q, and two Yahoo-specific fields, site and results, in the instance box, as can be seen in Listing 1.


Listing 1. The XML data structure, Part 1

<!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>

Perhaps the first thing noticeably unique about this XHTML is the use of the xmlns:y="urn:yahoo:srch" in the HTML tag This relates to the Yahoo search data instance. Yahoo returns their search data using xmlns="urn:yahoo:srch". Because Yahoo identifies that specific namespace, you also have to use that namespace when referencing that data; otherwise, it appears "invisible." Later it will be seen that all the XForms code referencing Yahoo search results uses the y: that was specified in the header. (Remember, the prefix doesn't matter; it's the actual namespace that counts.) Here, in the instance definition, the namespace is called out for the results XML data node.

The box instance includes both generic information (2) and site-specific information (appid, site, and results). You control the appearance of the site-specific information based on the value of the engine element. For example, you have binding elements that specify that the site and results elements are only "relevant" when the engine is "Yahoo." Later, when you create the actual form, you will see that while these items are on the page, they only appear if they are relevant. You will use the submitYahoo and submitTeoma elements to similarly control the visibility of the Submit buttons.

The last thing to note is fairly subtle, but can become a significant tripping point later in the design. Each instance is named box, yahoo, and teoma, as seen in Listing 1. Remember that these names are now specific to these instance data structures. They may not be used anywhere else as an identifier. It would be tempting in this case to re-use the IDs teoma and yahoo later in the switch/case/toggle mechanism, but that will not work because those names refer to the instance data.


The submission definition

The remainder of the data portion of the XForm is shown in Listing 2. The two remaining items are the submission elements. This example uses two separate submissions, one for each search. There are three things to note concerning these submission elements. They each play a key role in allowing the "background search" to happen without a page reload. Each submission element specifies a replace and an instance keyword. Notice that each submission element references the instance by the name chosen from Listing 1. This mechanism specifies that the data returned from this submission will replace the XML data at the named instance node. This is how a search is cleared and replaced with a new search result. Notice that both submission elements use ref="instance('box')". This instructs the submission action to use the XML of the box instance as input and since the whole point of this engine is to allow the user to search different engines without typing the same search string into each separately, both submission elements reference the same input data. The Yahoo-specific information is also passed to the Teoma search engine, but is just ignored by the Teoma PHP proxy.


Listing 2. The XML data structure, Part 2

      <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>

Both submission definitions use an <engine>proxy.php PHP script. This script is virtually the same for each, differing only in the base URL and the data included. These PHP scripts use the cURL extensions to retrieve the XML data from the respective search engines and echo that data back to the XForm allowing the data processing to be handled in the XForms implementation. Listing 3 shows the Yahoo PHP script. As stated above, the Teoma script is nearly identical.


Listing 3. The Yahoo proxy script

<?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;

?>

Because you used GET for the submission method, the PHP script received this information just as it would from a traditional Web form. Once you have the appropriate URL for the search, cURL takes the information submitted and returns the result.

You also have the option to use the POST method, but if you do, make sure to deal with URL encoding the data properly. You also might wish to have the XML directly submitted to the form in a situation in which you need to submit to a search engine API. For example, the MSN Live Search API requires a SOAP transaction. Listing 4 gives you a taste of dealing with the information submitted using POST.


Listing 4. The PHP Yahoo proxy script using POST

<?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;
...

Now let's look at the form itself.


The XForms presentation

There are two basic portions of the XForms presentation: the input portion and the output portion. These two separate portions interact with each other to provide a seamless interface to radically different underlying data structures, which are defined by each search engine and not under the control of the XForms author. Listing 5 shows the first portion, in the input portion.

The XForms input presentation

Some things to note about the input portion of the XForms presentation are the method used to link the search text with the q node in the box instance and the toggle elements of the submit definitions. Those toggle lines are what controls the switching between the two cases in the output section. This is where the caveat mentioned earlier of paying special attention to the names that have been defined already becomes important. In this case, the Teoma search case is named teo instead of teoma so it does not conflict with the instance name, and a similar naming is true for the Yahoo submission.


Listing 5. The XForms presentation code, Part 1

  <body>
    <p>
      <xforms:select1 ref="instance('box')/engine">
         <xforms:label>Choose a search engine:  </xforms:label>
         <xforms:item>
            
<xforms:label>Yahoo</xforms:label><xforms:value>Yahoo</xforms:value>
         </xforms:item>
         <xforms:item>
            
<xforms:label>Teoma</xforms:label><xforms:value>Teoma</xforms:value>
         </xforms:item>
      </xforms:select1>

   </p>
    <p>
      <xforms:input ref="instance('box')//q" >
        <xforms:label>Search Text: </xforms:label>
      </xforms:input>

      <xforms:input ref="instance('box')/site" >
        <xforms:label>Site: </xforms:label>
      </xforms:input>

      <xforms:select1 ref="instance('box')/results" >
        <xforms:label>Results displayed: </xforms:label>
        <xforms:item>
            <xforms:label>Ten</xforms:label>
            <xforms:value>10</xforms:value>
        </xforms:item>
        <xforms:item>
            <xforms:label>Twenty</xforms:label>
            <xforms:value>20</xforms:value>
        </xforms:item>
        <xforms:item>
            <xforms:label>Thirty</xforms:label>
            <xforms:value>30</xforms:value>
        </xforms:item>
      </xforms:select1>

    </p>
    <p>
      <xforms:submit submission="submit_teoma" ref="instance('box')/submitTeoma">
        <xforms:label>Search using Teoma</xforms:label>
        <xforms:toggle ev:event="DOMActivate" case="teo"/>
      </xforms:submit>

      <xforms:submit submission="submit_yahoo" ref="instance('box')/submitYahoo">
        <xforms:label>Search using Yahoo!</xforms:label>
        <xforms:toggle ev:event="DOMActivate" case="yah"/>
      </xforms:submit>
    </p>

Notice that all of the information is listed on the form, including the site-specific fields. Notice also that both buttons are listed on the page at the same time. The actual appearance of this data, however, is dependent upon the value of the engine field, controlled by the select list at the top. If the value is Yahoo, all of the Yahoo information appears, as in Figure 1. If it is Teoma, the Teoma information appears, as in Figure 2.


Figure 2. Searching using Teoma
Searching using Teoma

The XForms output presentation

Several valuable features of XForms, such as the "repeat" and the "switch/case" features, enable the seamless unified presentation of the two differently formatted search results. Listing 6 shows the output portion of the XForms presentation.


Listing 6. The XForms presentation code, Part 2

      <xforms:label><h3>Search Results:</h3></xforms:label>
    <xforms:switch>
      <xforms:case id="teo" selected="true">
        <xforms:repeat nodeset="instance('teoma')//RESULT">
          <p>
            <xforms:label><b>Title:</b> <xforms:output 
ref="TITLE"/></xforms:label><br/>
            <xforms:label><b>URL:</b> <xforms:output 
ref="URL"/></xforms:label><br/>
            <xforms:label><b>Description:</b> <xforms:output 
ref="ABSTRACT"/></xforms:label>
          </p>
        </xforms:repeat>
      </xforms:case>

      <xforms:case id="yah">
        <xforms:repeat nodeset="instance('yahoo')//y:Result">
          <p>
            <xforms:label><b>Title:</b> <xforms:output 
ref="y:Title"/></xforms:label><br/>
            <xforms:label><b>URL:</b> <xforms:output 
ref="y:Url"/></xforms:label><br/>
            <xforms:label><b>Description:</b> <xforms:output 
ref="y:Summary"/></xforms:label>
          </p>
        </xforms:repeat>
      </xforms:case>
    </xforms:switch>
    
  </body>
</html

The first thing to notice is the switch statement, which works in conjunction with the enclosed case statements. The prior section discussed the two submission elements and highlighted two statements in each submit definition that referenced the same tokens these case statement reference, teo and yah. That toggle action enables exactly one of these cases at any given time. The effect is that only one of the enclosed XForms definitions will be displayed.

Inside the case statements, the basic format of both the Yahoo and the Teoma output displays is very similar. When the search engine runs, it will generate many results nodes. For most search engine APIs, the number of search items returned is configurable, so the number of results nodes could change if this interface were enhanced to support that feature. XForms processes the "repeat" for each node it finds in the XML data structure, thus creating a listing of the results without the XForms author having to know the number before-hand and without having to alter the page source data structure with JavaScript to provide a display element for each node.

Figure 3 shows a search result for Teoma. Teoma is the simpler of the two output cases. The structure of the XML returned by Teoma is documented on their Web site (see Resources for a link). Since Teoma did not specify a namespace with their data, the nodes can be referenced by the names given in the XML only.


Figure 3. The Teoma search results
The Teoma search results

Figure 4 shows a search result for Yahoo, taking into account Yahoo's ability to limit results to a single site and to determine how many results to display. Yahoo's XML field names are different from Teoma but there is one other important difference: Yahoo specifies a namespace in the returned XML. This requires that the XForms references use that namespace. The namespace was defined at the header of the XHTML document as y. Listing 4 shows these y: specifiers in bold on all the XForms ref specifiers.


Figure 4. The Yahoo search results
The Yahoo search results

Summary

XForms gives you a great deal of flexibility in terms of what you display and what you don't display, enabling you to adapt to different situations on the fly for a more seamless user experience. In this article, we looked at making use of some of that power by creating a search client that presents a different interface depending upon the user's choice of search engine. You can take these concepts and use them for your own XForms-based applications, creating interfaces that adapt to user choices and the available data.



Download

DescriptionNameSizeDownload method
sample codedynamic_search.zip2KB HTTP

Information about download methods


Resources

Learn

Get products and technologies

Discuss

About the author

Stony Yakovac is an engineer and freelance author living in Lava Hot Springs, Idaho. He works on a wide variety of projects, including software and digital hardware designs.

Report abuse help

Report abuse

Thank you. This entry has been flagged for moderator attention.


Report abuse help

Report abuse

Report abuse submission failed. Please try again later.


developerWorks: Sign in


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

Choose your display name

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


Rate this article

Comments

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=XML
ArticleID=200284
ArticleTitle=Use XForms to create a dynamic Web search
publish-date=03062007
author1-email=syakovac@gmail.com
author1-email-cc=

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

For articles in technology zones (such as Java technology, Linux, Open source, XML), Popular tags shows the top tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), Popular tags shows the top tags for just that product zone.

For articles in technology zones (such as Java technology, Linux, Open source, XML), My tags shows your tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), My tags shows your tags for just that product zone.

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Try IBM PureSystems. No charge.

Special offers