Ajax|web|web Services | scripts
This article briefly introduces the ECMAScript (ECMAScript for xml,e4x) that can be used for XML, which is a simple extension of JavaScript, which makes it very simple to write XML scripts. In this article, the author demonstrates a WEB programming model called Asynchronous JavaScript and XML (asynchronous JavaScript and Xml,ajax) and shows you how some of the new XML extensions for JavaScript make it easier to implement.
ECMAScript for XML
You may not have encountered this term ECMAScript before. It is actually the official name of JavaScript. The European Computer Manufacturers Association (European Computer Manufacturers ASSOCIATION,ECMA) is a standardized organization for the development of JAVASCRIPT standards (while C # and CLR standards are also developed by the Association). The ECMAScript standard can be obtained free of charge from the ECMA Web site.
E4X is an extension of JavaScript, which actually adds direct support to XML in JavaScript. It is also a ECMA standard (see Resources--ecma-357). So what is its direct support for XML? Why does it have a high value? If you're a JavaScript programmer, you might have used something like Netscape liveconnect or Rhino (a free Jav that runs under Java™) Ascript Library) To use these Java libraries in your JavaScript. This means that you can already create, manipulate, and use XML with the help of an XML library. Similarly, if you are using Microsoft®internet Explorer, you have obtained XML support through the Microsoft MSXML2 library. That way, if you've already used those library files, be prepared to make important changes--e4x easier and easier.
Before we look at the sample example, we need to be aware of the experiment: there are two E4X implementations available at this time. Both of these options are available from Mozilla. One is the C JavaScript engine used by browsers (which is named SpiderMonkey by code) and is available in the latest Mozilla version-we use Mozilla 1.8a6. E4X is also available in Rhino. Rhino is a Java-built JavaScript interpreter and compiler, and we'll show you how to use it and run it inside of Axis. Both can be obtained from Mozilla.
In these sample instances, we start with the e4x on the command line using Rhino, and then we turn to the use of e4x within the browser using Mozilla, while demonstrating the AJAX model. In the second article, we'll show you how to use the e4x inside the server by embedding Rhino in the Apache Axis Web service engine. But before we turn to WEB services, we'll show you the basics of XML programming in e4x.
A simple example
Let's start with a simple example. We first analyze and manipulate the XML that represents the relevant information about the author. The XML we want is as follows:
Listing 1. Author XML document
<people>
<person gender= "Male" >
<name>Ant</name>
<eyes>Blue</eyes>
</person>
<person gender= "Male" >
<name>Paul</name>
<eyes>Grey</eyes>
</person>
</people>
If we get the XML document as a string, we can "parse" the string by using the following simple actions:
var x = new XML (peoplexmlstring);
Alternatively, we can simply "embed" the XML into the code:
var x =
<people>
<person gender= "Male" >
<name>Ant</name>
<eyes>Blue</eyes>
</person>
<person gender= "Male" >
<name>Paul</name>
<eyes>Grey</eyes>
</person>
</people>;
Use e4x via Rhino
If you're doing exactly the same thing as we do, you can now try the operation. The latest version of Rhino 1.6R1 and the XMLBeans Library from Apache support E4X. Using them is very simple, just get these packages, unzip them, and add Js.jar and Xbean.jar to your classpath, you can start the JavaScript handler.
JAVA-CP Js.jar;xbean.jar
Org.mozilla.javascript.tools.shell.Main
You can now try the following examples. You can cut and copy them from there, or include them in the Examples1.js file, which is in a zip file (ws-ajax1code.zip), and you can download the file by clicking the code icon at the top or bottom of this article.
You can view any part of the XML simply by using the properties of JavaScript. For example:
Print (x.person[0].name);
Ant
Print (X.person[1].hair);
Spiky
Have you noticed that, so far, we haven't used XML APIs such as DOM or SAX. XML just becomes a local type that JavaScript can understand.
Use the following code to print the height of two people:
For each (Var h in X..) Height) {print (h)};
176
178
syntax is very useful. It returns all of the child elements of any depth that can match the tag name immediately following it. So x.. Height returns the value of the height marker.
Here's another useful syntax:
Print (X.person. ( name== "Ant"). Hair);
Shaggy
This makes it easy to view operations in the XML tree.
A more complex sample instance
Suppose you want to change the height value from the metric unit to the Anglo-American system (that is, the feet and inch units that the British often say).
The next step is centimeter to inch conversion ...
function Metrictoimperial (CMS) {
var totalinches = Math.Round (cms/2.54);
var inch = totalinches%12;
var ft = (totalinches-inch)/12;
var response =
Response.feet = ft;
Response.inches = inch + 2; We sounded a bit short
Response. @measure = "Imperial";
return response;
}
The first notable line is:
var response =
This line allows you to "embed" XML into JavaScript. There are two advantages to adopting this syntax: first, it does make XML easy to use. Second, the meaning of these codes is very clear.
You can now add more child elements to the element:
Response.feet = ft;
This creates a
You can also manipulate its properties in this way:
Response. @measure = "Imperial";
Now we use this feature to update the XML:
For each (var p in X.person) {
if (p.height. @measure = = "Metric")
P.height=metrictoimperial (P.height);
}
print (x);
Here is the output:
<people>
<person gender= "Male" >
<name>Ant</name>
<eyes>Blue</eyes>
<feet>5</feet>
<inches>11</inches>
</person>
<person gender= "Male" >
<name>Paul</name>
<eyes>Grey</eyes>
<feet>5</feet>
<inches>12</inches>
</person>
</people>XML Namespaces in e4x (Namespace)
If you're an XML whiz, you might want to know how to use this syntax to manage XML namespaces at this point. Here are three ways to implement this:
First, you can use the embedded XML syntax:
var soapmsg = <s:envelope xmlns:s= "Http://www.w3.org/2003/05/soap-envelope"/>;
Print (Soapmsg.namespace ());
Http://www.w3.org/2003/05/soap-envelope
The second method is to set the default XML namespace before creating the element:
Default XML namespace = new namespace ("Http://www.w3.org/2003/05/soap-envelope");
You can set it to an empty string to reset the default namespace, for example:
Default XML namespace = ""
The last method is to use:: operator
var f = new Namespace ("http://fremantle.org");
Soapmsg.body.f::getstockquote= "IBM";
Print (soapmsg);
<s:envelope xmlns:s= "Http://www.w3.org/2003/05/soap-envelope" >
<s:Body>
<frem:getstockquote xmlns:frem= "http://fremantle.org" >
Ibm
</frem:GetStockQuote>
</s:Body>
</s:Envelope>XML element Sorting
An obvious advantage of e4x is that it fully supports XML, including sorting capabilities. Many direct mappings from XML documents to corresponding programming language objects only support XML semantic subsets that conform to common object semantics-thus losing the ability to represent objects as well as documents. However, for this article, it is not appropriate, as long as a simple review of the specification can be seen, e4x XML objects have the built-in capabilities of the XML elements can be meticulous and accurate sorting.
Using Javascript expressions in XML
Before we turn to the WEB service, we'll introduce you to the last one--using curly braces "{}". The above is a description of "embedded" XML. E4X also allows you to re-enter the JAVASCRIPT environment and can include the evaluated expression values. For example:
var num = 36;
var p = <paul><age>{num}</age></paul>
Print (p);
<paul>
<age>36</age>
</paul>
So far, we've covered the basics of e4x, so we can use these basics to do the following.
Using E4X to invoke a WEB service
In this section, we will describe how to use e4x in the following two environments:
1. Mozilla 1.8 using XMLHttpRequest
2. Java/rhino
You can easily invoke a Web service using e4x in your browser. But there's a problem! So far, the only browser that supports E4X is the Pro version of Mozilla 1.8. However, we do not recommend it as a portable cross-browser solution, and the following example demonstrates how E4X can invoke a Web service in an easy way. In the next section, we'll look at another way to run in the Rhino JavaScript engine.
Ajax
The sample instance shows the browser that sends and receives SOAP messages to the SOAP server. To do this, we use E4X by XMLHttpRequest objects. This object is very useful, and Mozilla and Internet Explorer browsers support it, allowing the scripting language running inside the browser to generate HTTP requests in the background. In fact, that's why Google's GMail can do anything. This architecture has recently been killed as asynchronous Javascript+xml (AJAX).
Essentially, AJAX is designed to improve the responsiveness and usability of WEB pages by interacting with servers in a more flexible way than the standard HTML and HTTP "page" models. A good example of this is the Google Maps beta, which is significantly more interactive than the previous mapping Web site.
Encouragingly, according to news reports, the performance of the AJAX combined with e4x is better! We will show you two versions of the browser application. The first version demonstrates the interaction, while the second version hides the buttons and internal work processes on the Web page to demonstrate interactivity and asynchrony.
Security for browsers
To demonstrate the security of the browser, we used the standard WEB services available on the xmethods.net. However, there is a problem, because in general, the browser's security rules do not allow scripting or Java applets to create a network connection, unless you are establishing a network connection to the server that generated the page. Otherwise, you need to have a monitoring page that will "copy" your key action to another server.
But you can avoid this kind of operation. To do this, you need to take two steps. First, you must enable the upgrade privileges in the Mozilla configuration for scripting programs. (assuming you have downloaded and installed the Mozilla 1.8 beta).
Enter About:config in the address bar of the browser, and then update the Signed.applets.codebase_principal_support value from False to true. (For security reasons, remember to set the original value back after you complete the operation.) )
Then, in a script program, you can request the use of upgrade privileges. When the scripting language runs, the user is prompted to use these privileges. Code behavior:
Netscape.security.PrivilegeManager.enablePrivilege ("Universalxpconnect universalbrowseraccess");
Stock Quote Client Sample
This script is part of the stockclient.html. If you download the Ws-ajax1code.zip file from this article, unzip the zip content and then use Mozilla to open stockclient.html, you will see the following:
Figure 1. The stockclient.html in Mozilla
To validate it, first click the Update URL. This action is done by using the XMLHttpRequest object from HTTP://SERVICES.XMETHODS.NET/SOAP/URN:XMETHODS-DELAYED-QUOTES.WSDL (or any URL you type in the WSDL box) Get the WSDL file, and then use E4X to get the port address URL from there. Now click Send, and you will see that the SOAP request is filled in. After two seconds, this SOAP response should be updated with the result field. Let's look at the code.
The Stock Quote Client script program
The script invokes the specified URL with request for the IBM stock price. If you are using the Axis server, then we recommend using the ticker symbol XXX, which is a special symbol--the deployed service will always return a fixed response for the tape recorder, rather than generating a WEB request to get the real stock price--so it would be better to test it with that symbol.
The first thing you have to do is define the e4x you want to use:
<script type= "Text/javascript;e4x=1" >
When you press the Send button, the script appears as follows:
var s = new Namespace (
"S",
"http://schemas.xmlsoap.org/soap/envelope/");
var envelope = <s:envelope xmlns:s={s}/>;
Envelope.s::body= "";
var body = Envelope.s::body;
This operation is generic to any SOAP request. It simply creates a SOAP envelope and does not include any message bodies. an equivalent implementation of this operation is shown below:
var envelope =
<s:envelope xmlns:s= "http://schemas.xmlsoap.org/soap/envelope/" >
<s:Body/>
</s:Envelope>
However, the preceding code is easier and gives you pointers to the principal element.
The next step is to create the body of the message:
var x = new Namespace ("X", "urn:xmltoday-delayed-quotes");
Body.x::getquote = <x:getquote xmlns:x={x}/>;
Finally, you must add the correct symbols:
var symbol = document.getElementById ("symbol"). Value;
var getquote = Body.x::getquote;
Getquote.symbol=symbol;
<s:envelope xmlns:s= "http://schemas.xmlsoap.org/soap/envelope/" >
<s:Body>
<x:getquote xmlns:x= "Urn:xmethods-delayed-quotes" >
<symbol>XXX</symbol>
</x:getQuote>
</s:Body>
</s:Envelope>
In order to send it, you must use the XMLHttpRequest object. We have created a simple helper function to support the use of XMLHttpRequest objects to invoke services that use e4x. This execservice function supports not only asynchronous methods but also synchronous methods.
function Execservice (URL, XML, callback) {
var xmlhttp = new XMLHttpRequest ();
var Async=false;
if (arguments.length==3) async=true;
Xmlhttp.open ("POST", url, async);
Xmlhttp.setrequestheader ("SOAPAction", "\" \ ")"
Xmlhttp.setrequestheader ("Content-type", "Text/xml")
if (async) {
var f = function () {
if (xmlhttp.readystate==4) {
Callback (New XML (Xmlhttp.responsetext));
}
}
Xmlhttp.onreadystatechange = f;
}
Xmlhttp.send (Xml.tostring ());
if (!async) return new XML (Xmlhttp.responsetext);
}
Let's take a look at the code in detail here. First, the code supports two ways of calling. You can use one of these:
XML execservice (string URL, XML envelope), or void Execservice (string URL, XML envelope, function callback);
In this case, the callback function should be a void callback (XML x).
You can then use this function to invoke the XML service directly and wait for the response, or you can transfer a function that calls the function using an XML response message.
The function determines whether it is asynchronous or synchronous (3 is asynchronous) based on the number of parameters, and then simply uses the XMLHttpRequest object to post the XML message to the HTTP request information and send the request to the specified URL.
We set up two HTTP header information--soapaction and content-type--then use Xmlhttp.send (Xml.tostring ()) to send the SOAP envelope message.
If the invocation behavior is asynchronous, it waits until the readyState is 4 (all complete) before invoking the XML callback function created from the response.
So the code that uses this action looks like this:
var url = document.getElementById ("url"). Value;
var callback = function (RESP) {
Alert (resp. *::getquotereturn);
}
Execservice (URL, envelope, callback);
In our sample, we use an asynchronous model. A typical Web browser is not blocked when talking to a server, and we don't want it to be that way. For example, if we block the browser, the browser's window may eventually behave as a "no response" state, prompting the user to end it.
resp.. *::getquotereturnIf you are a novice e4x, you need to understand the syntax again ... means to search for a named element from the tree. *:: Means any namespace, so the value will be a numeric value called the Getquotereturn element in any namespace that responds to the SOAP package.
The actual sample code stockclient.html also shows the request and response SOAP encapsulation. Test the sample--you should see the following:
Figure 2. Display request and response stockclient.html of SOAP encapsulation
The stockclient.html looks like a traditional Web page that uses the Submit button, although it's not actually (the browser has been viewing the page and never changed it). We created the file so that you can understand the interaction behavior. However, the real AJAX version of the page is much more beautiful. There are no buttons for this stockclientajax.html. As you type the operation, it automatically updates the stock price. Test the sample.
Although the page does not have a button, it can automatically make a request as soon as you stop typing (it waits 0.6 seconds before making a request so it can "sense" when you stop).
To generate a Web service request from Rhino
Rhino doesn't support XMLHttpRequest objects, but you don't have to worry about that. Because Rhino is running in the Java environment, you can use the Java feature to generate WEB service requests. To demonstrate this, we wrote a simple Java implementation of the XMLHttpRequest object. Rhino allows Java programmers to publish the Java language to extend their JavaScript environment. In order to use the XMLHttpRequest object in the Rhino shell, you only need to make sure that E4xutils.jar is in its own classpath, and then you can add it to your environment using the shell command, DefineClass:
>set Classpath=.\js.jar; \xbean.jar;. \e4xutils.jar;.
>java Org.mozilla.javascript.tools.shell.Main
Rhino 1.6 Release 1 30H
Js> defineclass (' xmlhttp. XMLHttpRequest ');
Here's a very simple script to test it:
>test.js
DefineClass ("xmlhttp.") XMLHttpRequest ");
var xh = new XMLHttpRequest ();
Xh.open ("Get",
"HTTP://SERVICES.XMETHODS.NET/SOAP/URN:XMETHODS-DELAYED-QUOTES.WSDL",
FALSE);
Xh.send (NULL);
var wsdl = new XML (xh.responsetext);
Print (WSDL.. *::address. @location);
>java Org.mozilla.javascript.tools.shell.Main Test.js
Http://64.124.140.30:9090/soap
The result is that you can now use the same script that you have written to (E4x+xmlhttprequest) in Mozilla and Rhino.
Conclusion
So far, you've seen how to use e4x and Javascript to initialize WEB service requests.
<