在以CLDC?基?的架?上分析XML

发表于:2007-06-22来源:作者:点击数: 标签:
越?越多的?用程式使用XML交??息。譬如,以 CLDC ?基?的?用程式 需要去?理 XML 文件,甚至? HTML ??也??很有可能??成?一?以 XML ?基?的格式。而?意味著?一???伺服器??一???而取出?料??需要分析 XML 的技?。 XML就是「可?展???言」,是一??便的、以文字?基?的

   越?越多的?用程式使用XML交??息。譬如,以 CLDC ?基?的?用程式 需要去?理 XML 文件,甚至? HTML ??也??很有可能??成?一?以 XML ?基?的格式。而?意味著?一???伺服器??一???而取出?料??需要分析 XML 的技?。

XML就是「可?展???言」,是一??便的、以文字?基?的方法去呈???化的?料。

越?越多的?用程式使用 XML 交??息,甚且,在一些情?下,您以 CLDC ?基?的?用程式 (?些是指在以 CLDC ?基?的架?上?行的,像是微小的手??置之?的) 需要去?理 XML 文件。之後,甚至? HTML ??也??很有可能??成?一?以 XML ?基?的格式,?? XHTML。?意味著?一???伺服器??一???而取出?料??需要分析 XML 的技?。

?找一?以 JAVA ?基?的 XML 分析器不?,尤其是自?有好??以 XML ?基?的的提倡?始被定?? Java ?理程序的一部分。然而,大部分的 XML 分析器?不支援在 CLDC 所提供的有限?源?境下?作。?些分析器不是使用了太多的???就是使用在 CLDC 下不能?作的 J2SETM ??。

然而,在?有??能在 CLDC ?境下?作的?放原始? XML 分析器 ── kXML 和 NanoXML。他?二者的??有些不同 ── 本文????他??者,?且提供您如何去?定哪一?是最?合您的程式需求。然而,您也??考?是否?? XML,因? XML 文件是非常冗?的。

如果您能?控制伺服器端,去使用您自己的二?位的格式去交??料才是有意?的。

如果一?以 Java ?基?的客?端?一?以 Java ?基?的伺服器端相互?通,?是相?容易的。在???例?,使用 DataInputStream 和 DataOutputStream ??,以?便的方法??取?料。

基本的 XML 分析器型?
基本的 XML 分析器型?有??:??性的和非??性的。

一???性的分析器透?一?文件型?定?或概要 (schema) ??一份 XML 文件,以?保?份文件的?容是程式所?期的。??要求???低?理的速度。一?非??性的分析器跳???步?,只保??? XML 文件是合乎基本格式的 (well-formed),?而言之,它遵守一般 XML 文件必?遵守的??。kXML 和 NanoXML 二者都是非??性的分析器。

 非??性的分析器
XML 分析器也能以他?如何?理和呈? XML 文件??分。

NanoXML 是一??一步? (single-step) 分析器。?定一份文件,NanoXML 以一??一的?作分析它,???份文件以一???的???回。kXML,相?之下,是一?多步?的 (multi-step) 的分析器 ── 一次分析文件的一??域。

???方法各有利弊,如果您正在?理一份?大的文件,?一步?的方法使用?多的???,因?全部的文件都?存在???中。但是?一步?的方法??有效率,如果您需要穿越?份文件很多次。多步?的方法能???易的?理?大的文件,但是您必?做?多的簿? (bookkeeping) 去追?您在文件的哪一?地方。

■ ?如何使用 kXML 呢?

? http://www.kxml.org/ 下? kXML 原始?,?且? kXML ??包含?您的?用程式。?不是所有的??都是需要的,所以只要下?包含最小 kXML 的 ZIP ?。在安?完???案後,新增下面的引入?述到您的程式中。
clearcase/" target="_blank" >cccccc border=1>


import org.kxml.*;
import org.kxml.parser.*;



?您??好去分析一份文件?,?生一? XmlParser ????,?入一?字元 (character) 流?唯一的??。



try {
Reader r = .....;
XmlParser parser = new XmlParser( r );
}
catch( java.io.IOException e ){
// handle exception....
}



如果您的文件是以字串被?存,?例??,您可以藉著??字串成?一?位元? (byte) ?列??取它,然後,?合 InputStreamReader 和 ByteArrayInputStream:



// ?取字串 (exception handling omitted)
String xml = "some xml";
ByteArrayInputStream bin =
new ByteArrayInputStream( xml.getBytes() );
XmlParser parser = new XmlParser( new InputStreamReader( bin ) );



然而,更可能?生的情?是,??路接收一份文件,?例??,在 CLDC 的通常??架? (GCF),您使用 MIDP ?建支援 HTTP 的???做?件事,然後您?使用 GCF 回?的?入流 (input stream),?且??它成?字元流 (character stream):



// Read from web (exception handling omitted)
HttpConnection conn = .....;
InputStreamReader doc =
new InputStreamReader( conn.openInputStream() );
XmlParser parser = new XmlParser( doc );



析器被?生後,您呼叫它的 read 方法去?取文件分?的??。read 方法?文件的每一?元件回?一? ParseEvent 物件:



try {
boolean keepParsing = true;
while( keepParsing ){
ParseEvent event = parser.read();
switch( event.getType() ){
case Xml.START_TAG:
..... // handle start of an XML tag
break;
case Xml.END_TAG:
..... // handle end of an XML tag
break;
case Xml.TEXT:
..... // handle text within a tag
break;
case Xml.WHITESPACE:
..... // handle whitespace
break;
case Xml.COMMENT:
..... // handle comment
break;
case Xml.PROCESSING_INSTRUCTION:
..... // handle XML PI
break;
case Xml.DOCTYPE:
..... // handle XML doctype
break;
case Xml.END_DOCUMENT:
..... // end of document;
keepParsing = false;
break;
}
}
}
catch( java.io.IOException e ){
}



ParseEvent ???回?的元件??定?了?多方法。getType 方法,?例??,回?元件的型?,像是它是否是一??? (tag) 的??、一??解等。其他的方法提供了?外的?息,像是一???的?文或一???的?性。? END_DOCUMENT 事件被???,分析器便停止?作。

kXML 使得?一?文件??下降的分析方式?的相?容易,分析器的??是被呼叫方法?持,??的反映到一?新的分析事件。在??的情?下,您可以利用??方法?保持追?您最後一?看?的??。

使用 NanoXML,必?下?一些原始?。官方的 NanoXML ?站是 http://nanoxml.sourceforge.net/。

一?修改?的 NanoXML 版本,能?? CLDC ?存 (原本的 NanoXML 只?合以 J2SE ?基?的系?) 可以在 http://www.ericgiguere.com/nanoxml 找到。就像 kXML,必?? NanoXML 包含到您的程式中,然後新增下面的引入?序到您的程式:

import nanoxml.*;

去分析一份文件,?生一? kXMLElement ??的??,?且??使用 parseFromReader、parseString 或 parseCharArray 其中之一:

由於 NanoXML 是一??一步?的分析器,它分析全部的文件,?且??它成?一???的XML元件。???的根部是您所?生的 kXMLElement ??,且每一????的??是另一? kXMLElement ??。您可以使用像是 getChildren、getTagName 和 getContents 的方法穿越?棵?。

去示?如何分析,??提供一? MIDP 程式。填?一?字串,包含了?多 XML 的元件,??程式使用 kXML。以 NanoXML 分析的?,?呼叫 parseUsingNanoXML ?行的?解符? (//) 去掉,??呼叫 parseUsingkXML ?行????解。??程式的一?完整的?案也是可以利用的 http://www.ericgiguere.com/techtips/XMLTest.zip,你可以使用 J2ME Wireless Toolkit ??行???案。



package com.ericgiguere.techtips;

import java.io.*;
import java.util.*;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
import nanoxml.*;
import org.kxml.*;
import org.kxml.parser.*;

/**
* Simple MIDlet that demonstrates how an XML document can be
* parsed using kXML or NanoXML.
*/

public class XMLTest extends MIDlet {

// Our XML document -- normally this would be something you
// download.

private static String xmlDocument =
"apple" +
"orange" +
"pear
";

private Display display;
private Command exitCommand = new Command( "Exit",
Command.EXIT, 1 );

public XMLTest(){
}

protected void destroyApp( boolean unconditional )
throws MIDletStateChangeException {
exitMIDlet();
}

protected void pauseApp(){
}

protected void startApp() throws MIDletStateChangeException {
if( display == null ){ // first time called...
initMIDlet();
}
}

private void initMIDlet(){
display = Display.getDisplay( this );

String [] items;

//items = parseUsingNanoXML( xmlDocument );
items = parseUsingkXML( xmlDocument );

display.setCurrent( new ItemList( items ) );
}

public void exitMIDlet(){
notifyDestroyed();
}

// Parses a document using NanoXML, looking for
// "item" nodes and returning their content as an
// array of strings.

private String[] parseUsingNanoXML( String xml ){
kXMLElement root = new kXMLElement();

try {
root.parseString( xml );

Vector list = root.getChildren();
Vector items = new Vector();

for( int i = 0; i < list.size(); ++i ){
kXMLElement node =
(kXMLElement) list.elementAt( i );
String tag = node.getTagName();

if( tag == null ) continue;
if( !tag.equals( "item" ) ) continue;

items.addElement( node.getContents() );
}

String[] tmp = new String[ items.size() ];
items.copyInto( tmp );
return tmp;
}
catch( kXMLParseException ke ){
return new String[]{ ke.toString() };
}
}

// Parses a document using kXML, looking for "item"
// nodes and returning their content as an
// array of strings.

private String[] parseUsingkXML( String xml ){
try {
ByteArrayInputStream bin =
new ByteArrayInputStream(
xml.getBytes() );
InputStreamReader in = new InputStreamReader( bin );
XmlParser parser = new XmlParser( in );
Vector items = new Vector();

parsekXMLItems( parser, items );

String[] tmp = new String[ items.size() ];
items.copyInto( tmp );

return tmp;
}
catch( IOException e ){
return new String[]{ e.toString() };
}
}

private void parsekXMLItems( XmlParser parser, Vector items )
throws IOException {
boolean inItem = false;

while( true ){
ParseEvent event = parser.read();
switch( event.getType() ){
case Xml.START_TAG:
if( event.getName().equals( "item" ) ){
inItem = true;
}
break;
case Xml.END_TAG:
if( event.getName().equals( "item" ) ){
inItem = false;
}
break;
case Xml.TEXT:
if( inItem ){
items.addElement( event.getText() );

}
break;
case Xml.END_DOCUMENT:
return;
}
}
}

// Simple List UI component for displaying the list of
// items parsed from the XML document.

class ItemList extends List implements CommandListener {

ItemList( String[] list ){
super( "Items", IMPLICIT, list, null );
addCommand( exitCommand );
setCommandListener( this );
}

public void commandAction( Command c, Displayable d ){
if( c == exitCommand ){
exitMIDlet();
}
}
}
}


原文转自:http://www.ltesting.net