`

XML基础 (4)

 
阅读更多

DOM4j 是一致评价很高的一款开源XML解析器 支持XPath XML XSLT DOM SAX 和 JAXP并自带了一个SAX解析器

可以说是一个 20% - 80% 的工具(这个好像是JDOM的声明)

先看看API

org.dom4j.DocumentHelper

这个类的所有的方法都是static的 可以简单的用来创建document element attribute 等等

org.dom4j.DocumentFactory

这个类是工厂方法的集合用来简单构建DOM4J树

OutputFormat

这个类用来设置格式和字符编码等等

XMLWriter

标准的输出类

Document和Element都是实现了Brance这个接口

现在利用DOM4J来简单的输出一个xml文档

importorg.dom4j.DocumentException;
importorg.dom4j.DocumentFactory;
importorg.dom4j.Element;
importorg.dom4j.io.OutputFormat;
importorg.dom4j.io.XMLWriter;

publicclassTestWriteXML
...{

publicstaticvoidmain(String[]args)throwsIOException,DocumentException
...{
DocumentFactorydFactory
=DocumentFactory.getInstance();
Documentdoc
=dFactory.createDocument();
Elementelement
=dFactory.createElement("ergal");

doc.setRootElement(element);

element.addAttribute(
"id","007");

ElementeName
=element.addElement("name");
ElementeAge
=element.addElement("age");

eName.setText(
"wang");
eAge.setText(
"24");

FileOutputStreamfos
=newFileOutputStream("test.xml");
OutputFormatof
=newOutputFormat("",true);
XMLWriterxw
=newXMLWriter(fos,of);

xw.write(doc);
xw.close();

}

}

中间用OutputFormat来设置了格式

还有如果是用java.io.Write构造的输出不会自动刷新 需要在write之后手动刷新

输出:

<?xmlversion="1.0"encoding="UTF-8"?>

<ergalid="007">
<name>wang</name>
<age>24</age>
</ergal>

我这用的是DocumentFactory 也可以用DocumentHelper的static方法来实现 Element也可以

packagecom.ergal;

importjava.io.FileOutputStream;
importjava.io.IOException;
importorg.dom4j.Document;
importorg.dom4j.DocumentHelper;
importorg.dom4j.DocumentException;
importorg.dom4j.DocumentFactory;
importorg.dom4j.Element;
importorg.dom4j.io.OutputFormat;
importorg.dom4j.io.XMLWriter;

publicclassTestWriteXML
...{

publicstaticvoidmain(String[]args)throwsIOException,DocumentException
...{
//DocumentFactorydFactory=DocumentFactory.getInstance();

//Documentdoc=dFactory.createDocument();
Documentdoc=DocumentHelper.createDocument();
Elementelement
=DocumentHelper.createElement("ergal");

doc.setRootElement(element);

element.addAttribute(
"id","007");

ElementeName
=element.addElement("name");
ElementeAge
=element.addElement("age");

eName.setText(
"wang");
eAge.setText(
"24");

FileOutputStreamfos
=newFileOutputStream("test.xml");
OutputFormatof
=newOutputFormat("",true);
XMLWriterxw
=newXMLWriter(fos,of);

xw.write(doc);
xw.close();

}

}

结果是一样的

SAX

现在来看DOM4J的SAX的实现

解析XML的方法有很多 SAX是性能较好的一种 在DOM4J中用SAXReader来获得DOM4J树

在DOM4J中 和JAXP一样 Node是核心 其他的接口(如Attribut Document等等)都是对Node的扩展

在JAXP中的Node没有accept方法 在DOM4J中Node多了一种方法accept

void accept(Visitorvisitor)
accept is the method used in the Visitor Pattern.

此方法允许你传进一个实现了Visitor的类 这个类一看API就知道了

void visit(Attributenode)
Visits the given Attribute
void visit(CDATAnode)
Visits the given CDATA
void visit(Commentnode)
Visits the given Comment
void visit(Documentdocument)
Visits the given Document
void visit(DocumentTypedocumentType)
Visits the given DocumentType
void visit(Elementnode)
Visits the given Element
void visit(Entitynode)
Visits the given Entity
void visit(Namespacenamespace)
Visits the given Namespace
void visit(ProcessingInstructionnode)
Visits the given ProcessingInstruction
void visit(Textnode)
Visits the given Text

可以定制回调时所用的类 这个实现了Visitor的类的方法 可以自己添加处理方式来根据自己的需要解析XML

实例:解析一个XML

hibernate.cfg.xml

<?xmlversion='1.0'encoding='UTF-8'?>
<!DOCTYPEhibernate-configurationPUBLIC
"-//Hibernate/HibernateConfigurationDTD3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"
>

<!--GeneratedbyMyEclipseHibernateTools.-->
<hibernate-configuration>
<session-factory>
<propertyname="connection.driver_class">com.mysql.jdbc.Driver</property>
<propertyname="connection.url">jdbc:mysql://localhost:3306/sshtest</property>
<propertyname="connection.username">root</property>
<propertyname="connection.password">00000000</property>

<!--JDBCconnectionpool-->
<propertyname="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
<propertyname="hibernate.c3p0.max_size">20</property>
<propertyname="hibernate.c3p0.min_size">5</property>
<propertyname="hibernate.c3p0.timeout">120</property>
<propertyname="hibernate.c3p0.max_statements">100</property>
<propertyname="hibernate.c3p0.idle_test_period">120</property>
<propertyname="hibernate.c3p0.acquire_increment">2</property>

<propertyname="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>

<!--SQLdialect-->
<propertyname="dialect">org.hibernate.dialect.MySQLDialect</property>
<propertyname="current_session_context_class">thread</property>
<propertyname="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<propertyname="show_sql">true</property>
<!--<propertyname="hbm2ddl.auto">create</property>-->

<mappingresource="com/ergal/hibernate/pojo/User.hbm.xml"/>
<mappingresource="com/ergal/hibernate/pojo/Artist.hbm.xml"/>
<mappingresource="com/ergal/hibernate/pojo/Category.hbm.xml"/>
<mappingresource="com/ergal/hibernate/pojo/FileType.hbm.xml"/>
<mappingresource="com/ergal/hibernate/pojo/MyFile.hbm.xml"/>
<mappingresource="com/ergal/hibernate/pojo/MyLocation.hbm.xml"/>
<mappingresource="com/ergal/hibernate/pojo/MyPackage.hbm.xml"/>
<mappingresource="com/ergal/hibernate/pojo/MyPic.hbm.xml"/>

</session-factory>
</hibernate-configuration>

先写一个类来扩展VisitorSupport

SAXParserTest.java

packagecom.ergal;

importorg.dom4j.Attribute;
importorg.dom4j.Element;
importorg.dom4j.VisitorSupport;

publicclassSAXParserTestextendsVisitorSupport
...{
//打印属性的名字和值
publicvoidvisit(Attributenode)
...{
System.out.println(
"attribute:"+node.getName()+"value:"+node.getValue());
}

publicvoidvisit(Elementnode)
...{
//如果只有文本就打印元素名和文本
if(node.isTextOnly())
...{
System.out.println(
"element:"+node.getName()+"text:"+node.getTextTrim());
}

//否则只打印元素名
else
...{
System.out.println(
"element:"+node.getName());
}

}


}

然后写一个解析的类

ParserTest.java

packagecom.ergal;

importjava.io.File;
importorg.dom4j.Document;
importorg.dom4j.DocumentException;
importorg.dom4j.io.SAXReader;


publicclassParserTest
...{
publicstaticvoidmain(String[]args)
...{
SAXReadersr
=newSAXReader();
Filef
=newFile("bin/hibernate.cfg.xml");
try
...{
Documentdoc
=sr.read(f);
doc.accept(
newSAXParserTest());

}
catch(DocumentExceptione)
...{
System.out.println(e.getMessage());
}

}

}

最后的输出如下:

element:hibernate-configuration
element:session-factory
element:propertytext:com.mysql.jdbc.Driver
attribute:namevalue:connection.driver_class
element:propertytext:jdbc:mysql://localhost:3306/sshtest
attribute:namevalue:connection.url
element:propertytext:root
attribute:namevalue:connection.username
element:propertytext:00000000
attribute:namevalue:connection.password
element:propertytext:org.hibernate.connection.C3P0ConnectionProvider
attribute:namevalue:hibernate.connection.provider_class
element:propertytext:20
attribute:namevalue:hibernate.c3p0.max_size
element:propertytext:5
attribute:namevalue:hibernate.c3p0.min_size
element:propertytext:120
attribute:namevalue:hibernate.c3p0.timeout
element:propertytext:100
attribute:namevalue:hibernate.c3p0.max_statements
element:propertytext:120
attribute:namevalue:hibernate.c3p0.idle_test_period
element:propertytext:2
attribute:namevalue:hibernate.c3p0.acquire_increment
element:propertytext:org.hibernate.transaction.JDBCTransactionFactory
attribute:namevalue:hibernate.transaction.factory_class
element:propertytext:org.hibernate.dialect.MySQLDialect
attribute:namevalue:dialect
element:propertytext:thread
attribute:namevalue:current_session_context_class
element:propertytext:org.hibernate.cache.NoCacheProvider
attribute:namevalue:cache.provider_class
element:propertytext:true
attribute:namevalue:show_sql
element:mappingtext:
attribute:resourcevalue:com/ergal/hibernate/pojo/User.hbm.xml
element:mappingtext:
attribute:resourcevalue:com/ergal/hibernate/pojo/Artist.hbm.xml
element:mappingtext:
attribute:resourcevalue:com/ergal/hibernate/pojo/Category.hbm.xml
element:mappingtext:
attribute:resourcevalue:com/ergal/hibernate/pojo/FileType.hbm.xml
element:mappingtext:
attribute:resourcevalue:com/ergal/hibernate/pojo/MyFile.hbm.xml
element:mappingtext:
attribute:resourcevalue:com/ergal/hibernate/pojo/MyLocation.hbm.xml
element:mappingtext:
attribute:resourcevalue:com/ergal/hibernate/pojo/MyPackage.hbm.xml
element:mappingtext:
attribute:resourcevalue:com/ergal/hibernate/pojo/MyPic.hbm.xml

可以看到完全是和过程相关的 有什么节点就怎么解析 碰到元素就调用元素的事件 碰到属性就调用属性的事件

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics