分享
 
 
 

如何使用kxml解析WAP

王朝other·作者佚名  2008-05-31
窄屏简体版  字體: |||超大  

如何使用kXML解析WAP

作者cleverpig

版权声明:任何获得Matrix授权的网站,转载时请务必以超链接形式标明文章原始出处和作者信息及本声明

作者:cleverpig(http://www.matrix.org.cn/blog/cleverpig)

原文:http://www.matrix.org.cn/resource/article/43/43909_Kxml_Wap.Html

要害字:j2me,wap,kxml

一、两种访问方法:

目前的kxml支持两种wap格式:WBXML/WML。

而有两种方法将解析WBXML:

1。使用j2me将WBXML转换到XML;

2。使用kxml直接解析WBXML流。下面我在这里讨论一下使用第二种方法实现client代码解析WBXML,当然要使用kxml了。

二、kxml实现方法:

首先需要位于web server的应用程序通过开放WAP网关(关于JWAP:详见http://jwap.sourceforge.net/)发送WML文件给j2me client。在WAP网关将数据发送j2me client之前WAP网关将WML文件转换为了WBXML文件。下面代码的展示了j2me client如何接收WBXML数据,解析数据,并显示有用的数据在手机屏幕上。

需要注重,在本例程中使用的kxml v1.0版本,kxml v2.0版本在使用上可能有所不同,开发者可以参考kxml2的手册。

import Java.io.*;

import org.kxml.*;

import org.kxml.parser.*;

import org.kxml.wap.*;

import javax.microedition.lcdui.*;

import javax.microedition.midlet.*;

import javax.microedition.io.*;

public class WbxmlTest extends MIDlet implements CommandListener

{

private Display display = null;

private List menu = null;

private Form form = null;

private String incomingText = "";

static final Command okCommand

= new Command("Ok", Command.OK, 1);

static final Command exitCommand

= new Command("Exit", Command.EXIT, 0);

// This is a hard coded WSP message that contains

// address of web server where our jsp page is located.

byte[] message ={

(byte)'1',(byte)0x40,(byte)0x3D,(byte)'h',(byte)'t',

(byte)'t',(byte)'p',(byte)':',(byte)'/',(byte)'/',

(byte)'l',(byte)'o',(byte)'c',(byte)'a',(byte)'l',

(byte)'h',(byte)'o',(byte)'s',(byte)'t',(byte)':',

(byte)'8',(byte)'0',(byte)'8',(byte)'0',(byte)'/',

(byte)'e',(byte)'x',(byte)'a',(byte)'m',(byte)'p',

(byte)'l',(byte)'e',(byte)'s',(byte)'/',(byte)'j',

(byte)'s',(byte)'p',(byte)'/',(byte)'f',(byte)'i',

(byte)'n',(byte)'a',(byte)'l',(byte)'f',(byte)'i',

(byte)'l',(byte)'e',(byte)'s',(byte)'/',(byte)'D',

(byte)'a',(byte)'t',(byte)'.',(byte)'j',(byte)'s',

(byte)'p',(byte)0x80,(byte)0x94,(byte)0x88,(byte)0x81,

(byte)0x6A,(byte)0x04,(byte)0x83,(byte)0x99

};

// Memory space to receive message.

byte[] msg = new byte [256];

public void pauseApp() { /* ----- */ }

public void destroyApp(boolean unconditional)

{ notifyDestroyed(); }

public void startApp() {

display = Display.getDisplay(this);

this.mainMenu();

}//startApp

//Displays the menu screen

private void mainMenu() {

menu = new List(" Send Request", Choice.IMPLICIT);

menu.append(" Send Message",null);

menu.addCommand(okCommand);

menu.setCommandListener(this);

display.setCurrent(menu);

}//mainMenu

//Display the reply from WAPGateway (JWap).

private void showReply() {

form = new Form( "Incoming Message" );

form.append("The price = " + incomingText);

form.addCommand(exitCommand);

form.setCommandListener(this);

display.setCurrent(form);

}//showReply

// Makes a WSP Connection with a WAPGateway,

// Sends a message and receives the reply.

public void getConnect() {

Datagram dgram =null;

DatagramConnection dc=null;

try {

dc = (DatagramConnection)Connector.open ("datagram://127.0.0.1:9200");

dgram = dc.newDatagram(message, message.length);

try{

dc.send(dgram);}

catch (InterruptedIOException e){

e.printStackTrace(); }

dgram = dc.newDatagram (msg,msg.length);

try{

dc.receive(dgram);}

catch (InterruptedIOException e){

e.printStackTrace();}

catch( IOException e){

e.printStackTrace();}

// This is the most interesting part.

incomingText = this.getIncomingTextOfWmlc(dgram.getData());

this.showReply();

dc.close();

}//try

catch (IllegalArgumentException ie){

ie.printStackTrace(); }

catch (ConnectionNotFoundException cnf){

cnf.printStackTrace(); }

catch (IOException e){e.printStackTrace();}

}//getConnect()

private String getIncomingTextOfWmlc ( byte[] wmlc ) {

try {

// Remove WSP header.

// We know it is 19 bytes for our case.

// But for real world applications,

// this should be dynamically deteced.

for ( int j = 0; j < wmlc.length-19; j++ )

wmlc[j] = wmlc[j+19];

WmlParser parser = new WmlParser(new ByteArrayInputStream(wmlc));

while (true) {

try {

ParseEvent parseEvent = parser.read();

if ( parseEvent.getType() == Xml.START_TAG ) {

Attribute attr =

parseEvent.getAttribute("value");

if ( attr != null )

return attr.getValue();

}//if

}//try

catch ( IOException e) {}

}//while

}//try

catch ( IOException e) { e.printStackTrace(); }

return "error";

}//getIncomingTextOfWmlc

public void commandAction(Command c, Displayable d) {

String commandlabel = c.getLabel();

if (commandlabel.equals("Exit"))

destroyApp(false);

else if (commandlabel.equals("Ok"))

getConnect();

}//commandAction

}//class WbxmlTest

为了演示目的,除了建立一个web Server外,还要在本机建立一个JWAP Server。

三、代码说明:

上面的代码将数据连接请求发送到了本机的JWAP Server的URL:“datagram://127.0.0.1:9200”,并发送了一个硬编码的WSP(wireless Session Protocol)请求:http://localhost:8080/examples/jsp/finalfiles/Dat.jsp,然后等待并读取JWAP Server的回应,在接收到回应信息后使用kxml解析提取其中的数据(元素属性名为“value”的属性值)。在解析完成后,将数据显示于手机屏幕上。

代码中的getConnect 方法建立与JWAP Server的连接,并发送请求给JWAP Server,要求访问web Server上的http://localhost:8080/examples/jsp/finalfiles/Dat.jsp,在接收到JWAP Server发回的请求后,getConnect方法调用getIncomingTextOfWmlc方法提取接收到的WBXML数据。由于j2me client与JWAP Server之间的通讯使用了WAP协议堆栈,所以j2me client接收的数据中包含WSP头,在getIncomingTextOfWmlc方法中首先去掉了这个WSP头。

之后,getIncomingTextOfWmlc方法使用KXML的事件解析机制进行了4步操作:

1。传入保存WBXML数据的字节数组构造WmlParser 对象;

2。调用WmlParser的read方法,找到第一个TAG开始的地方;

3。读取“value”属性值;

4。回到第2步进行2、3之间的循环,直到找不到START_TAG。

四、数据流程:

而在JWAP网关接收到j2me client发来的硬编码请求后,将这个请求转发给了web Server,本例程中的web Server为http://localhost:8080。web Server接收到请求后,使用一个硬编码的WML文件作为回应:

<?xml version="1.0"?>

<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml">

<%@ page language="java" contentType= "text/vnd.wap.wml" %>

<wml>

<card id="c0" newcontext="false" ordered="false">

<input type="Price" value="15224" emptyok="false"/>

</card>

</wml>

当JWAP网关接收到这个web Server的WML文件后,将其转换为WBXML格式并修改其content-type编码为WBXML,最后将转换后的WBXML格式数据发给了j2me client。

五、总结:

使用kxml方法避免了XML与WBXML之间的相互转换,WBXML文件的格式减少了XML文件的大小,不仅可将WBXML用于WAP设备,也可以用于基于web的程序与无线设备之间的通讯和数据交换。

六、参考资源:

Compressing XML

jWAP

kxml

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有