1、XML解析(dom4j)
1.1 读取XML文档
public Document read ( String fileName) throws MalformedURLException, DocumentException {
SAXReader reader = new SAXReader ( ) ;
Document document = reader. read ( new File ( fileName) ) ;
return document;
}
1.2 获取ROOT节点
public Element getRootElement ( Document doc) {
return doc. getRootElement ( ) ;
}
1.3 遍历XML树
1.3.1 列举3中遍历方法:
1.3.1.1 枚举(Iterator)
for ( Iterator i = root. elementIterator ( ) ; i. hasNext ( ) ; ) {
Element element = ( Element) i. next ( ) ;
}
for ( Iterator i = root. elementIterator ( foo) ; i. hasNext ( ) ; ) {
Element foo = ( Element) i. next ( ) ;
}
for ( Iterator i = root. attributeIterator ( ) ; i. hasNext ( ) ; ) {
Attribute attribute = ( Attribute) i. next ( ) ;
}
1.3.1.2 递归
public void treeWalk ( ) {
Document document = read ( "XML文件路径" ) ;
treeWalk ( getRootElement ( document) ) ;
}
public void treeWalk ( Element element) {
for ( int i = 0 , size = element. nodeCount ( ) ; i < size; i++ ) {
Node node = element. node ( i) ;
if ( node instanceof Element ) {
treeWalk ( ( Element) node) ;
} else {
}
}
}
1.3.1.3 Visitor模式
Visitor是自动遍历所有子节点的。如果是root. accept ( MyVisitor) ,将遍历子节点
1 、定义一个类继承VisitorSupport(实现了Visitor接口)
public class MyVisitor extends VisitorSupport {
public MyVisitor ( ) {
}
@Override
public void visit ( Document document) {
System. out. println ( "visit-document = [" + document. asXML ( ) + "]" ) ;
}
@Override
public void visit ( DocumentType documentType) {
super . visit ( documentType) ;
}
@Override
public void visit ( Element node) {
if ( node. isTextOnly ( ) ) {
System. out. println ( node. getName ( ) + " " + ":" + " " + node. getText ( ) ) ;
} else {
System. out. println ( "node = [" + node. getName ( ) + "]" ) ;
}
}
@Override
public void visit ( Attribute node) {
super . visit ( node) ;
}
@Override
public void visit ( CDATA node) {
super . visit ( node) ;
}
@Override
public void visit ( Comment node) {
super . visit ( node) ;
}
@Override
public void visit ( Entity node) {
super . visit ( node) ;
}
@Override
public void visit ( Namespace namespace) {
super . visit ( namespace) ;
}
@Override
public void visit ( ProcessingInstruction node) {
super . visit ( node) ;
}
@Override
public void visit ( Text node) {
super . visit ( node) ;
}
}
2 、调用visit方法
public static void main ( String[ ] args) throws DocumentException {
MyVisitor myVisitor = new MyVisitor ( ) ;
String resSucc = "<result><MSG><MSG><array><AAC>*****</AAC><AAE>****</AAE><AAA>*</AAA><AAC>*</AAC><AAC>***</AAC><AAC>********</AAC><AAC>******</AAC></array></MSG><SUCCESS>****</SUCCESS></MSG><SUCCESS>****</SUCCESS></result>" ;
Document document = DocumentHelper. parseText ( resSucc) ;
document. accept ( myVisitor) ;
System. out. println ( "=================================" ) ;
Element rootElement = document. getRootElement ( ) ;
rootElement. accept ( myVisitor) ;
}
3 、执行结果:
visit- document = [ < ? xml version= "1.0" encoding= "UTF-8" ? >
< result> < MSG> < MSG> < array> < AAC> * * * * * < / AAC> < AAE> * * * * < / AAE> < AAA> * < / AAA> < AAC> * < / AAC> < AAC> * * * < / AAC> < AAC> * * * * * * * * < / AAC> < AAC> * * * * * * < / AAC> < / array> < / MSG> < SUCCESS> * * * * < / SUCCESS> < / MSG> < SUCCESS> * * * * < / SUCCESS> < / result> ]
node = [ result]
node = [ MSG]
node = [ MSG]
node = [ array]
AAC : * * * * *
AAE : * * * *
AAA : *
AAC : *
AAC : * * *
AAC : * * * * * * * *
AAC : * * * * * *
SUCCESS : * * * *
SUCCESS : * * * *
== == == == == == == == == == == == == == == == =
node = [ result]
node = [ MSG]
node = [ MSG]
node = [ array]
AAC : * * * * *
AAE : * * * *
AAA : *
AAC : *
AAC : * * *
AAC : * * * * * * * *
AAC : * * * * * *
SUCCESS : * * * *
SUCCESS : * * * *
之所以会打印两遍子节点的信息,是因为document. accept ( myVisitor) 中调用了Element的accpt ( ) 方法, 即rootElement. accept ( myVisitor)
String text = "<skills>\n" +
"<!--第一个技能-->\n" +
"<skill name=\"独孤九剑\">\n" +
"<info>为独孤求败所创,变化万千,凌厉无比。其传人主要有风清扬、令狐冲。</info>\n" +
"</skill>\n" +
"<skill name=\"葵花宝典\">\n" +
"<info>宦官所创,博大精深,而且凶险至极。练宝典功夫时,首先要自宫净身。</info>\n" +
"</skill>\n" +
"<skill name=\"北冥神功\">\n" +
"<info>逍遥派的顶级内功之一,能吸人内力转化为自己所有,威力无穷。</info>\n" +
"</skill>\n" +
"</skills>" ;
Document document1 = DocumentHelper. parseText ( text) ;
Element rootElement1 = document1. getRootElement ( ) ;
Element skill = rootElement1. element ( "skill" ) ;
skill. accept ( new Visitor ( ) {
@Override
public void visit ( Document document) {
}
@Override
public void visit ( DocumentType documentType) {
}
@Override
public void visit ( Element element) {
System. out. println ( "element = [" + element. asXML ( ) + "]" ) ;
}
@Override
public void visit ( Attribute attribute) {
}
@Override
public void visit ( CDATA cdata) {
}
@Override
public void visit ( Comment comment) {
}
@Override
public void visit ( Entity entity) {
}
@Override
public void visit ( Namespace namespace) {
}
@Override
public void visit ( ProcessingInstruction processingInstruction) {
}
@Override
public void visit ( Text text) {
}
} ) ;
1.4 XPath支持
selectNodes语法:
String resSucc = "<result><MSG><MSG name=\"测试\"><array><AAC>*****</AAC><AAE>****</AAE><AAA>*</AAA><AAC>*</AAC><AAC>***</AAC><AAC>********</AAC><AAC>******</AAC></array></MSG><SUCCESS>****</SUCCESS></MSG><SUCCESS>****</SUCCESS></result>" ;
Document document = DocumentHelper. parseText ( resSucc) ;
Element rootElement = document. getRootElement ( ) ;
List< Node> nodes = rootElement. selectNodes ( "MSG" ) ;
nodes. forEach ( ( node - > {
System. out. println ( "node = [" + node. getName ( ) + "]" ) ;
} ) ) ;
nodes = rootElement. selectNodes ( "/MSG" ) ;
nodes. forEach ( ( node - > {
System. out. println ( "/node = [" + node. getName ( ) + "]" ) ;
} ) ) ;
nodes = rootElement. selectNodes ( "//MSG" ) ;
nodes. forEach ( ( node - > {
System. out. println ( "//node = [" + node. getName ( ) + "]" ) ;
} ) ) ;
nodes = rootElement. selectNodes ( "." ) ;
nodes. forEach ( ( node - > {
System. out. println ( ".node = [" + node. getName ( ) + "]" ) ;
} ) ) ;
nodes = rootElement. selectNodes ( ".." ) ;
nodes. forEach ( ( node - > {
System. out. println ( "..node = [" + node. getName ( ) + "]" ) ;
} ) ) ;
nodes = rootElement. selectNodes ( "//MSG[@name]" ) ;
nodes. forEach ( ( node - > {
System. out. println ( "[@name]node = [" + node. getName ( ) + "]" ) ;
} ) ) ;
nodes = rootElement. selectNodes ( "//MSG[@name='测试']" ) ;
nodes. forEach ( ( node - > {
System. out. println ( "[@name='测试']node = [" + node. getName ( ) + "]" ) ;
} ) ) ;
nodes = rootElement. selectSingleNodes ( "MSG" ) ;
nodes. forEach ( ( node - > {
System. out. println ( "node = [" + node. getName ( ) + "]" ) ;
} ) ) ;
1.5 字符串与XML相互转换
Document document = . . . ;
String text = document. asXML ( ) ;
String text = James ;
Document document = DocumentHelper. parseText ( text) ;
1.6 创建XML
public static void main ( String[ ] args) {
Document document = DocumentHelper. createDocument ( ) ;
Element root = document. addElement ( "root" ) ;
root
. addElement ( "author" )
. addAttribute ( "name" , "James" )
. addAttribute ( "location" , "UK" )
. addText ( "James Strachan" ) ;
root
. addElement ( "author" )
. addAttribute ( "name" , "Bob" )
. addAttribute ( "location" , "US" )
. addText ( "Bob McWhirter" ) ;
System. out. println ( "root:\n" + root. asXML ( ) + "]" ) ;
}
执行结果:
< root> < author name= "James" location= "UK" > James Strachan< / author> < author name= "Bob" location= "US" > Bob McWhirter< / author> < / root>
1.7 文件输出
此处代码接上一节代码:
System. out. println ( "文件输出准备······" ) ;
try {
OutputFormat format = OutputFormat. createPrettyPrint ( ) ;
format. setEncoding ( "UTF-8" ) ;
XMLWriter xmlWriter = new XMLWriter ( new FileOutputStream ( "C:\\Users\\Administrator\\Desktop\\CreateXml" +
".xml" ) , format) ;
xmlWriter. write ( root) ;
xmlWriter. close ( ) ;
} catch ( Exception e) {
System. out. println ( "文件输出失败:" + e. getMessage ( ) ) ;
throw e;
}
System. out. println ( "文件输出完成\n" ) ;
try {
OutputFormat format = OutputFormat. createPrettyPrint ( ) ;
format. setEncoding ( "UTF-8" ) ;
XMLWriter xmlWriter = new XMLWriter ( new FileWriter ( new File ( "C:\\Users\\Administrator\\Desktop\\CreateXml2.xml" ) ) , format) ;
xmlWriter. write ( root) ;
xmlWriter. close ( ) ;
} catch ( Exception e) {
System. out. println ( "文件输出失败:" + e. getMessage ( ) ) ;
throw e;
}
System. out. println ( "输出控制台开始" ) ;
try {
OutputFormat format = OutputFormat. createPrettyPrint ( ) ;
format. setEncoding ( "UTF-8" ) ;
XMLWriter writer = new XMLWriter ( System. out, format) ;
writer. write ( root) ;
writer. flush ( ) ;
} catch ( Exception e) {
System. out. println ( "文件输出失败:" + e. getMessage ( ) ) ;
throw e;
}
System. out. println ( "\n输出控制台完成" ) ;
1.8 xml节点解析方法
1.8.1 selectNodes() 和 selectSingleNode()
此处代码接1.6 节代码:
root. selectNodes ( "author" ) . forEach ( ( ele) - > {
System. out. println ( "eleName = [" + ele. getName ( ) + "]" ) ;
} ) ;
Node author = root. selectSingleNode ( "author" ) ;
System. out. println ( "node = [" + author. getText ( ) + "]" ) ;
System. out. println ( "node-path = [" + author. getPath ( ) + "]" ) ;
1.8.2 element() 和 elements()
此示例接1.6 节代码:
root. elements ( ) . forEach ( ( ele) - > {
System. out. println ( "eleName = [" + ele. getName ( ) + "]" ) ;
} ) ;
root. elements ( "author" ) . forEach ( ( ele) - > {
System. out. println ( "elements = [" + ele. getName ( ) + "]" ) ;
} ) ;
String result = "<result><MSG><MSG><array><AAC>**</AAC><AAE>*****</AAE></array></MSG></MSG></result>" ;
Document doc = DocumentHelper. parseText ( result) ;
Element rootElement = doc. getRootElement ( ) ;
int count = rootElement. element ( "MSG" ) . element ( "MSG" ) . elements ( ) . size ( ) ;
1.8.3 setName()
rootElement. element ( "MSG" ) . element ( "MSG" ) . setName ( "ERRMSG" ) ;
1.8.4 getText() 和 getStringValue()
String resSucc = "<result><MSG><MSG name=\"测试\"><array><AAC>*****</AAC><AAE>****</AAE><AAA>*</AAA><AAC>*</AAC><AAC>***</AAC><AAC>********</AAC><AAC>******</AAC></array></MSG><SU>****</SU></MSG><SU>****</SU></result>" ;
Document document = DocumentHelper. parseText ( resSucc) ;
System. out. println ( "StringValue = [" + document. getStringValue ( ) + "]" ) ;
System. out. println ( "Text = [" + document. getText ( ) + "]" ) ;
1.8.5 isTextOnly()
@Override
public void visit ( Element node) {
if ( node. isTextOnly ( ) ) {
System. out. println ( node. getName ( ) + " " + ":" + " " + node. getText ( ) ) ;
} else {
System. out. println ( "node = [" + node. getName ( ) + "]" ) ;
}
}
1.8.6 自定义递归方法遍历所有节点内容
String resSucc = "<result><MSG><MSG name=\"测试\"><array><AAC>*****</AAC><AAE>****</AAE><AAA>*</AAA><AAC>*</AAC><AAC>***</AAC><AAC>********</AAC><AAC>******</AAC></array></MSG><SU>****</SU></MSG><SU>****</SU></result>" ;
Document document = DocumentHelper. parseText ( resSucc) ;
Element rootElement = document. getRootElement ( ) ;
parse ( rootElement) ;
public static void parse ( Element root) {
List el = root. elements ( ) ;
for ( Object o : el) {
Element element = ( Element) o;
if ( element. isTextOnly ( ) ) {
List attList = element. attributes ( ) ;
for ( Object e : attList) {
System. out. println ( element. getQName ( ) . getName ( ) + "元素的" + ( ( Attribute) e) . getQName ( ) . getName ( ) +
"属性值为:" + ( ( Attribute) e) . getValue ( ) ) ;
}
System. out. println ( element. getTextTrim ( ) ) ;
} else {
parse ( element) ;
}
}
}
1.8.7 elementIterator()
public static Document load ( String filename) {
Document document = null;
try {
SAXReader saxReader = new SAXReader ( ) ;
document = saxReader. read ( new File ( filename) ) ;
} catch ( Exception ex) {
ex. printStackTrace ( ) ;
}
return document;
}
public boolean isOnly ( String catNameEn, HttpServletRequest request,
String xml) {
boolean flag = true ;
String path = request. getRealPath ( "" ) ;
Document doc = load ( path + "/" + xml) ;
Element root = doc. getRootElement ( ) ;
for ( Iterator i = root. elementIterator ( ) ; i. hasNext ( ) ; ) {
Element el = ( Element) i. next ( ) ;
if ( catNameEn. equals ( el. elementTextTrim ( "engName" ) ) ) {
flag = false ;
break ;
}
}
return flag;
}
1.8.8 Qname()
Qname:
1. 来历:qname是qualified name 的简写
2. 构成:由名字空间( namespace) 前缀( prefix) 以及冒号( : ) , 还有一个元素名称构成
3. 举例:
< xsl: stylesheet xmlns: xsl= "http://www.w3.org/1999/XSL/Transform"
xmlns= "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
version= "1.0" >
< xsl: template match= "foo" >
< hr/ >
< / xsl: template>
< / xsl: stylesheet>
xsl是名字空间前缀,template是元素名称,xsl: template 就是一个qname
4. 总结:qname无非是有着特定格式的xml元素,其作用主要是增加了名字空间,比如有同样的元素名称,而名字空间不同的情况。
public static void main ( String[ ] args) throws DocumentException {
String text = "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\"\n" +
"xmlns=\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\"\n" +
"version=\"1.0\">\n" +
"<xsl:template match=\"foo\">\n" +
"<hr/>\n" +
"</xsl:template>\n" +
"</xsl:stylesheet>" ;
Document document = DocumentHelper. parseText ( text) ;
Element rootElement = document. getRootElement ( ) ;
System. out. println ( "args = [" + rootElement. getQName ( ) . getNamespacePrefix ( ) + "]" ) ;
System. out. println ( "args = [" + rootElement. getQName ( ) . getQualifiedName ( ) + "]" ) ;
System. out. println ( "args = [" + rootElement. getQName ( "xsl:stylesheet" ) . getName ( ) + "]" ) ;
System. out. println ( "args = [" + rootElement. getQName ( ) . toString ( ) + "]" ) ;
System. out. println ( "args = [" + rootElement. getQName ( ) . getNamespace ( ) + "]" ) ;
}