StAX:Streaming API for XML ,如同字面意思,是基于流的API,相对于传统的DOM和SAX,StAX在性能和易用性上取得了很好的平衡。StAX是基于SAX的,同样将XML作为一组事件来处理,不过与SAX不同的是,StAX是采用拉(Pull)的方式来处理事件, 允许应用程序从事件流中拉出事件,而不是提供从解析器中接收事件的回调程序程序。
StAX 包括两套处理 XML 的 API,分别提供了不同程度的抽象。一种是基于指针的 API, 提供应用程序把 XML 作为一个标记(或事件)流来处理,这是一种低层 API,效率高,抽象程度低。另一种是较为高级的基于迭代器的 API, 提供应用程序把 XML 作为一系列事件对象来处理,每个对象和应用程序交换 XML 结构的一部分,应用程序直接处理这些代表了XML结构一部分的事件对象。
StAX在JDK6中已经内置了,或许就是以后的标准。
下面以一个简单的例子示范基于指针的API的使用。例子说明:从一个xml结构的订单信息中parse出Java对象,修改这个对象,然后输出为一个xml文件。
一、xml文件内容
xml version="1.0" encoding="UTF-8"
?>
DOCTYPE po SYSTEM "src/sample.dtd"
>
<
po
id
="po121"
submitted
="2001-10-05"
xmlns
="http://www.csdn.net"
>
<
billTo
id
="addr-1"
>
<
company
>
The Redzero Cop.
company
>
<
street
>
Jianguo Road 1ST
street
>
<
street
>
Building 1
street
>
<
city
>
Haidian
city
>
<
state
>
Beijing
state
>
<
postalCode
>
100071
postalCode
>
billTo
>
<
shipTo
href
="addr-1"
/>
<
order
>
<
item
sku
="o318-BP"
quantity
="5"
>
<
description
>
J2EE programmic
description
>
item
>
<
item
sku
="o947-TI"
quantity
="12"
>
<
description
>
Java WEB Service
description
>
item
>
<
item
sku
="o008-PR"
quantity
="133"
>
<
description
>
C++ develop
description
>
item
>
order
>
po
>
二、Java对象结构
public
class
Order
...
{
List items=newArrayList();
publicvoidaddItem(Item item)
...{
items.add(item);
} @Override
publicString toString()
...{
StringBuffer buf=newStringBuffer();
buf.append("order");
for(Iterator itr=items.iterator();itr.hasNext();)
...{
Item item=(Item)itr.next();
buf.append("item");
buf.append("sku=").append(item.getSku()).append("").append("quantity=").append(item.getQuantity()).append("")
.append("description=").append(item.getDescription()).append("");
}returnbuf.toString();
}}
public
class
Item
...
{
String sku;
intquantity;
String description;
publicString getDescription()
...{
returndescription;
}publicvoidsetDescription(String description)
...{
this.description=description;
}publicintgetQuantity()
...{
returnquantity;
}publicvoidsetQuantity(intquantity)
...{
this.quantity=quantity;
}publicString getSku()
...{
returnsku;
}publicvoidsetSku(String sku)
...{
this.sku=sku;
}}
三、解析示例,注意代码注释
解析
/** */
/** * 解析XML文档,把数据绑定到Java对象上
*@paramin
*@return*/
public
Order parse(InputStream in)
...
{
Stack stack=newStack();
try
...{
//1.得到XMLStreamReaderXMLInputFactory inputFactory=XMLInputFactory.newInstance();
XMLStreamReader reader=inputFactory.createXMLStreamReader(in);
while(reader.hasNext())
...{
//2.根据事件类型做相应的处理,对于多数应用来说,处理完成可以直接break,跳出循环,提高性能switch(reader.getEventType())
...{
caseXMLStreamReader.START_ELEMENT:
String name=reader.getLocalName();
if("order".equals(name))
...{
Order order=newOrder();
stack.push(order);
}elseif("item".equals(name))
...{
Item item=newItem();
String sku=reader.getAttributeValue(0);
String quantity=reader.getAttributeValue(1);
item.setSku(sku);
item.setQuantity(Integer.parseInt(quantity));
stack.push(item);
}elseif("description".equals(name))
...{
String desc=reader.getElementText();
Item item=(Item) stack.pop();
item.setDescription(desc);
Order order=(Order) stack.peek();
order.addItem(item);
}break;
} reader.next();//获取下一个解析事件} }catch(XMLStreamException e)
...{
e.printStackTrace();
}if(!stack.empty())
...{
return(Order) stack.pop();
}else
...{
returnnull;
} }
输出
/** */
/** * 使用StAX接口输出XML文档,无法自动输出格式良好的文档,必须自己控制文档的排版
*@paramorder
*@return*/
public
String write(Order order)
...
{
StringWriter buffer=newStringWriter();
try
...{
//1.得到XMLStrreamWriterXMLOutputFactory outputFactory=XMLOutputFactory.newInstance();
//修复名称空间前缀。
//对于任何在范围内不具有名称空间声明的属性,自动名称空间声明。
//如果元素或属性名称具有前缀,但没有绑定到任何名称空间 URI,则前缀将在序列化时被删除。outputFactory.setProperty("javax.xml.stream.isRepairingNamespaces",newBoolean(true));
XMLStreamWriter writer=outputFactory.createXMLStreamWriter(buffer);
//2.设置默认命名空间writer.setDefaultNamespace("http://www.csdn.net");
//3.开始输出文档writer.writeStartDocument("UTF-8","1.0");
writer.writeCharacters("");//换行,让输出的xml好看一点
//输出DTDwriter.writeDTD("po SYSTEM "src/sample.dtd">");
writer.writeCharacters("");
//输出xml文档的元素,输出一个start,必须要输出一个相应的endwriter.writeStartElement("po");//开始根元素po
//输出元素属性writer.writeAttribute("id","20080124001");
writer.writeAttribute("submitted","2008-01-24");
writer.writeCharacters("");
writer.writeStartElement("billTo");//开始billTo元素writer.writeAttribute("id","addr-1");
writer.writeCharacters("");
writer.writeStartElement("company");
writer.writeCharacters("CSDN");
writer.writeEndElement();
writer.writeCharacters("");
writer.writeStartElement("street");
writer.writeCharacters("朝阳区望京北路");
writer.writeEndElement();
writer.writeCharacters("");
writer.writeStartElement("city");
writer.writeCharacters("朝阳区");
writer.writeEndElement();
writer.writeCharacters("");
writer.writeStartElement("state");
writer.writeCharacters("北京");
writer.writeEndElement();
writer.writeCharacters("");
writer.writeStartElement("postalCode");
writer.writeCharacters("100102");
writer.writeEndElement();
writer.writeCharacters("");
writer.writeEndElement();//billTo元素结束 writer.writeCharacters("");
writer.writeStartElement("shipTo");//开始shipTo元素writer.writeAttribute("href","addr-1");
writer.writeEndElement();//shipTo元素结束 writer.writeCharacters("");
writer.writeStartElement("order");//开始order元素writer.writeCharacters("");
for(Iterator itr=order.items.iterator(); itr.hasNext();)
...{
Item item=(Item) itr.next();
writer.writeStartElement("item");
writer.writeAttribute("sku", item.getSku());
writer.writeAttribute("quantity", String.valueOf(item
.getQuantity()));
writer.writeCharacters("");
writer.writeStartElement("description");
writer.writeCharacters(item.getDescription());
writer.writeEndElement();
writer.writeCharacters("");
writer.writeEndElement();
writer.writeCharacters("");
} writer.writeEndElement();//order元素结束 writer.writeCharacters("");
writer.writeEndElement();//po元素结束writer.writeEndDocument();
writer.flush();
writer.close();
}catch(XMLStreamException e)
...{
e.printStackTrace();
}returnbuffer.toString();
}
代码测试,其中TestStax类为包含了上面解析与输出代码的类
TestStax stax = new TestStax();
Order order = stax.parse(XmlFile.getSample1Stream());
System.out.println(order.toString());
Item item = new Item();
item.setSku("0123-BP");
item.setQuantity(10);
item.setDescription("Java XML 开发");
order.addItem(item);
String xml = stax.write(order);
System.out.println("------------------------------");
System.out.println(xml);
XML输出结果
CSDN
朝阳区望京北路
朝阳区
北京
100102
J2EE programmic
Java WEB Service
C++ develop
Java XML 开发
没有什么多于的介绍,基本上就是一个代码示范,我相信二八法则,20%的知识基本能够满足80%可能碰到的场景,呵呵,算是谬论吧。
详细的介绍在IBM网站上有一篇,个人觉得还不错