最近用得到xml的解析方式,于是就翻了翻自己的笔记同时从网上查找了资料,自己在前人的基础上总结了下,贴出来大家分享下。
首先介绍一下xml语言:
可扩展标记语言 (Extensible Markup Language,XML) ,用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。
xml的语法:
XML分为两部分:头信息,主体信息
头信息是用来描述XML的一些属性,例如:版本,编码等,还可以提供XML显示的样式,和dtd编写格式。
主体信息中包含的是XML的具体数据。
头信息的语法:
<?xmlversion=”1.0”encoding=”GBK” ?>
其中version是必须加的,而encoding可以不写,则默认编码是ISO8859-1,不支持中文。
除了这个功能外,头信息还可以进行编写格式的规定,通过dtd或xsd文件。
头信息还支持样式表的导入,允许通过样式表控制XML的显示。
这样可以使用XML+ CSS完成页面的显示,通过这种形式完成MVC中的View层:
优点:代码的安全性很高,可以很容易的替换模板。
缺点:开发成本太高
主体信息就是由三种节点组成的,节点之间存在父与子的关系,注意的点:
一个节点只能有一个父节点,如果没有父节点,该节点称为根节点。
一个节点可以有多个子节点。只有元素节点可以拥有子节点。
元素节点的标记必须成对出现,或直接结束。
特殊字符必须转义。依据字符所处的位置是否对XML格式造成影响来决定是否进行转义
根节点只能有一个
xml常用的四种解析方式:
1)DOM(Document Object Model)
文档对象模型分析方式。以层次结构(类似于树型)来组织节点和信息片段,映射XML文档的结构,允许获取和操作文档的任意部分。是W3C的官方标准。
优点: 1、允许应用程序对数据和结构做出更改。 2、访问是双向的,可以在任何时候在树中上下导航,获取和操作任意部分的数据。
缺点: 1、通常需要加载整个XML文档来构造层次结构,消耗资源大
2)SAX(Simple API for XML)
流模型中的推模型分析方式。通过事件驱动,每发现一个节点就引发一个事件,通过回调方法完成解析工作,解析XML文档的逻辑需要应用程序完成。
优点: 1、不需要等待所有数据都被处理,分析就能立即开始。 2、只在读取数据时检查数据,不需要保存在内存中。 3、可以在某个条件得到满足时停止解析,不必解析整个文档。 4、效率和性能较高,能解析大于系统内存的文档。
缺点: 1、需要应用程序自己负责TAG的处理逻辑(例如维护父/子关系等),使用麻烦。 2、单向导航,很难同时访问同一文档的不同部分数据,不支持XPath。
3)JDOM(Java-based Document Object Model)
Java特定的文档对象模型。自身不包含解析器,使用SAX。
优点: 1、使用具体类而不是接口,简化了DOM的API。 2、大量使用了Java集合类,方便了Java开发人员。
缺点: 1、没有较好的灵活性。 2、性能较差。
4)DOM4J(Document Object Model for Java)
简单易用,采用Java集合框架,并完全支持DOM、SAX和JAXP。
优点: 1、大量使用了Java集合类,方便Java开发人员,同时提供一些提高性能的替代方法。 2、支持XPath。 3、有很好的性能。
缺点: 1、大量使用了接口,API较为复杂。
下面把四种解析方式的代码贴一下,首先是DOM方式
Java代码
publicclassDOMXml{
staticvoidcreateXML(StringoutputPath){
//建立Document对象
DocumentBuilderFactoryfactory=DocumentBuilderFactory.newInstance();
//创建DocumentBuilder
try{
DocumentBuilderdb=factory.newDocumentBuilder();
//创建Document,建立新的对象
Documentdoc=db.newDocument();
//建立各个节点
//元素节点
Elementallplus=doc.createElement("allplus");
Elementareaplus=doc.createElement("areaplus");
Elementid=doc.createElement("id");
Elementtitle=doc.createElement("title");
//创建文本节点
TextidText=doc.createTextNode("1");
TexttitleText=doc.createTextNode("123");
//配置父子节点的关系
id.appendChild(idText);
title.appendChild(titleText);
areaplus.appendChild(id);
areaplus.appendChild(title);
allplus.appendChild(areaplus);
//allplus是根节点,应该设置为doc的子节点
doc.appendChild(allplus);
//执行保存操作
TransformerFactorytf=TransformerFactory.newInstance();
Transformert=tf.newTransformer();
//包装要保存的doc
DOMSourcesource=newDOMSource(doc);
//设置输出流
StreamResultsr=newStreamResult(newFile(outputPath));
//设置输出的属性
t.setOutputProperty("encoding","UTF-8");
//t.setOutputProperty("version","1.0");
//输出
t.transform(source,sr);
}catch(DOMExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}catch(ParserConfigurationExceptione){
catch(Exceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
}
voidparseXML(StringxmlPath){
/*优点:整个文档树在内存中,便于操作;支持删除、修改、重新排列等多种功能;
*缺点:将整个文档调入内存(包括无用的节点),浪费时间和空间;
*使用场合:一旦解析了文档还需多次访问这些数据;硬件资源充足(内存、CPU)。
*10M文档导致内存溢出
*/
//创建Document,形成树型结构
Documentdoc=db.parse(newFile(xmlPath));
//先取得所有的data
NodeListdatas=doc.getElementsByTagName("data");
//循环取得每个data
for(inti=0;i<datas.getLength();i++){
Nodedata=datas.item(i);
//由于直接取得第一个和最后一个不符合要求,因此使用取得全部子节点的方式
NodeListactorInfos=data.getChildNodes();
intj=0;j<actorInfos.getLength();j++){
NodeactorInfo=actorInfos.item(j);
NodeListallChild=actorInfo.getChildNodes();
intt=0;t<allChild.getLength();t++){
//判断节点
Nodechild=allChild.item(t);
if(child.getNodeType()==Node.ELEMENT_NODE){
if(child.getNodeName().equals("id")){
//判断是否有孩子节点,然后再取值
if(child.hasChildNodes()){
System.out.println(child.getFirstChild().getNodeValue());
}
}
if(child.getNodeName().equals("name")){
if(child.hasChildNodes()){
System.out.println(child.getFirstChild().getNodeValue());
}
}
}
}
}
}
}catch(SAXExceptione){
catch(IOExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
}
voidmain(String[]args){
parseXML("D:/actor_info.xml");
createXML("d:/fxb.xml");
}
SAX解析方式
Java代码
classSAXXmlextendsDefaultHandler{
privateList<Book>books=null;
privateBookbook=privateStringpreTag=null;//作用是记录解析时的上一个节点名称
publicList<Book>getBooks(InputStreamxmlStream)throwsException{
SAXParserFactoryfactory=SAXParserFactory.newInstance();
SAXParserparser=factory.newSAXParser();
SAXXmlhandler=newSAXXml();
parser.parse(xmlStream,handler);
returnhandler.getBooks();
}
publicList<Book>getBooks(){
returnbooks;
}
@Override
voidstartDocument()throwsSAXException{
books=newArrayList<Book>();
}
voidstartElement(Stringuri,StringlocalName,StringqName,
Attributesattributes)throwsSAXException{
if("book".equals(qName)){
book=newBook();
book.setId(Integer.parseInt(attributes.getValue(0)));
}
preTag=qName;//将正在解析的节点名称赋给preTag
}
voidendElement(Stringuri,StringqName)
if("book".equals(qName)){
books.add(book);
book=null;
}
preTag=null;
/**
*当解析结束时置为空。这里很重要,例如,当图中画3的位置结束后,会调用这个方法
*,如果这里不把preTag置为null,根据startElement(....)方法,preTag的值还是book,当文档顺序读到图
*中标记4的位置时,会执行characters(char[]ch,intstart,int
*length)这个方法,而characters(....)方
*法判断preTag!=null,会执行if判断的代码,这样就会把空值赋值给book,这不是我们想要的。
*/
}
voidcharacters(char[]ch,intstart,85);font-weight: bold">intlength)
if(preTag!=null){
Stringcontent=newString(ch,start,length);
if("name".equals(preTag)){
book.setName(content);
}elseif("price".equals(preTag)){
book.setPrice(Float.parseFloat(content));
}
}
}
voidmain(Stringargs[]){
SAXXmlhandler=newSAXXml();
//定义SUN自带解析对象
SAXParserparser;
try{
parser=SAXParserFactory.newInstance().newSAXParser();
parser.parse(newFile("D:/book.xml"),handler);
}//TODOAuto-generatedcatchblock
e.printStackTrace();
}
List<Book>books=handler.getBooks();
for(Bookbook:books){
System.out.println(book.toString());
}
}
JDOM解析方式
Java代码
classJDOMXml{
//先建立Document对象
Documentdoc=newDocument();
//建立元素节点
Elementallplus=newElement("allplus");
try{
//建立多个Element
Elementareaplus=newElement("areaplus");
Elementid=newElement("id");
Elementtitle=newElement("title");
//设置节点内容
id.addContent("id");
title.addContent("title");
//设置父子节点关系
areaplus.addContent(id);
areaplus.addContent(title);
allplus.addContent(areaplus);
//设置根节点
doc.setRootElement(allplus);
//使用IO流操作
FileWriterwriter=newFileWriter(//定义输出对象
XMLOutputteroutputter=newXMLOutputter();
//设置编码
outputter.setEncoding("UTF-8");
//输出
outputter.output(doc,writer);
writer.close();
}voidparseXML(StringxmlPath){
/*
*/
//完成解析功能。
SAXBuilderbuilder=newSAXBuilder();
try{
Documentdoc=builder.build(//开始解析,取得根节点
Elementdata=doc.getRootElement();
//取得所有的areaplus
List<Element>actorInfos=data.getChildren("actor_info");
if(actorInfos!=null&&actorInfos.size()>0){
for(ElementactorInfo:actorInfos){
Elementid=actorInfo.getChild("id");
Elementname=actorInfo.getChild("name");
System.out.println(id.getTextTrim()+"---"+name.getTextTrim());
}
}
}catch(JDOMExceptione){
e.printStackTrace();
}catch(IOExceptione){
e.printStackTrace();
}
}
voidmain(String[]args){
parseXML("D:/actor_info.xml");
createXML("d:/fdfdsf.xml");
}
DOM4J解析方式
Java代码
packagecom.fxb.test;
importjava.io.File;
importjava.io.FileWriter;
importjava.io.IOException;
importjava.io.Writer;
importjava.util.Iterator;
importorg.dom4j.Document;
importorg.dom4j.DocumentException;
importorg.dom4j.DocumentHelper;
importorg.dom4j.Element;
importorg.dom4j.io.SAXReader;
importorg.dom4j.io.XMLWriter;
*
*@authorhongliang.dinghlDom4j生成XML文档与解析XML文档
*/
classDOM4JXml{
voidcreateXml(StringfileName){
Documentdocument=DocumentHelper.createDocument();
Elementemployees=document.addElement("data");
Elementemployee=employees.addElement("actor_info");
Elementid=employee.addElement("id");
id.setText("1");
Elementname=employee.addElement("name");
name.setText("你好");
Elementmessage=employee.addElement("message");
message.setText("你好吗");
Elementpic=employee.addElement("pic");
pic.setText("123");
Elementsex=employee.addElement("sex");
pic.setText("男");
Elementbirthday=employee.addElement("birthday");
pic.setText("19881212");
try{
WriterfileWriter=newFileWriter(fileName);
XMLWriterxmlWriter=newXMLWriter(fileWriter);
xmlWriter.write(document);
xmlWriter.close();
}catch(IOExceptione){
System.out.println(e.getMessage());
}
}
voidparserXml(StringfileName){
FileinputXml=newFile(fileName);
SAXReadersaxReader=newSAXReader();
try{
Documentdocument=saxReader.read(inputXml);
Elementdata=document.getRootElement();
for(Iteratori=data.elementIterator();i.hasNext();){
ElementactorInfo=(Element)i.next();
//System.out.println(employee.getName()+"->"+employee.getText());
for(Iteratorj=actorInfo.elementIterator();j.hasNext();){
Elementchild=(Element)j.next();
System.out.println(child.getName()+":"+child.getText());
}
System.out.println("=================");
}
}catch(DocumentExceptione){
System.out.println(e.getMessage());
}
}
voidmain(Stringargs[]){
DOM4JXmldom=newDOM4JXml();
//dom.parserXml("d:/actor_info.xml");
dom.createXml("d:/fxb.xml");
}
}
引用:http://lewis-fxb.iteye.com/blog/1243298 (编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|