javaxml解析list_详解Java中的XML解析
详解Java中的XML解析
前⾔
XML,全称Extensibible Markup Language, 主要⽤于数据的保存或者⽂件传输,其主要特性如下所⽰:
以标签为主的标记语⾔
⽀持⾃定义标签,⽀持⾃我解释
与具体技术⽆关
⽀持验证
⽅便⼈类的读写
XML⽰例
为了更好的了解XML,下⾯我们提供⼀个简单的XML⽂件,内容如下所⽰:
xuhuanfeng
22
male
Tom
23
femal
Lily
24
femal
在XML中每个元素都可以有⼦元素/值,元素可以有属性,具体关于XML的内容还请查看官⽅的⽂档,接下来的内容主要为Java对XML⽂件的解析。
XML解析
XML解析主要有两种⽅式,⼀种称为DOM解析,另外⼀种称之为SAX解析。
DOM解析:Document Object Model,简单的来讲,DOM解析就是读取XML⽂件,然后在⽂件⽂档描述的内容在内存中⽣成整个⽂档树。
SAX解析:Simple API for XML,简单的来讲,SAX是基于事件驱动的流式解析模式,⼀边去读⽂件,⼀边解析⽂件,在解析的过程并不保存具体的⽂件内容。
两种解析⽅式各有千秋,也都有各⾃的有点和缺点,这⾥简单罗列如下:
DOM解析:
优点:在内存中形成了整个⽂档树,有了⽂档树,就可以随便对⽂档中任意的节点进⾏操作(增加节点、删除节点、修改节点信息等),⽽且由于已经有了整个的⽂档树,可以实现对任意节点的随机访问。
缺点:由于需要在内存中形成⽂档树,需要消耗的内存⽐较⼤,尤其是当⽂件⽐较⼤的时候,消耗的代价还是不容⼩视的。
SAX解析:
优点:SAX解析由于是⼀边读取⽂档⼀边解析的,所以所占⽤的内存相对来说⽐较⼩。
缺点:⽆法保存⽂档的信息,⽆法实现随机访问节点,当⽂档需要编辑的时候,使⽤SAX解析就⽐较⿇烦了。对XML的两种不同解析机制有⼀定的了解之后,接下来我们就来具体的看下,在Java中是如何解析的。DOM解析
关于DOM的解析,这⾥就不再做过多的解释了,直接通过代码来查看具体的操作过程
解析⽂档
public void parse() {
// students的内容为上⾯所⽰XML代码内容
File file = new File("D:/l");
try {
// 创建⽂档解析的对象
DocumentBuilderFactory factory = wInstance();
DocumentBuilder builder = wDocumentBuilder();
// 解析⽂档,形成⽂档树,也就是⽣成Document对象
Document document = builder.parse(file);
// 获得根节点
Element rootElement = DocumentElement();
System.out.printf("Root Element: %s\n", NodeName());
// 获得根节点下的所有⼦节点
NodeList students = ChildNodes();
for (int i = 0; i < Length(); i++){
// 获得第i个⼦节点
Node childNode = students.item(i);
/
/ 由于节点多种类型,⽽⼀般我们需要处理的是元素节点
// 元素节点就是⾮空的⼦节点,也就是还有孩⼦的⼦节点
if (NodeType() == Node.ELEMENT_NODE){
Element childElement = (Element)childNode;
System.out.printf(" Element: %s\n", NodeName());
System.out.printf(" Attribute: id = %s\n", Attribute("id"));
// 获得第⼆级⼦元素
NodeList childNodes = ChildNodes();
for (int j = 0; j < Length(); j++){
Node child = childNodes.item(j);
if (NodeType() == Node.ELEMENT_NODE){
Element eChild = (Element) child;
System.out.printf(" sub Element: %s value= %s\n", NodeName(), TextContent());
}
}
}
}
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
解析的结果如下所⽰:
Root Element: students
Element: student
Attribute: id = 123
sub Element: name value= xuhuanfeng
sub Element: age value= 22
sub Element: gender value= male
# 其余两个student节点由于篇幅原因这⾥省略...
当我们需要特定的节点的数据的时候,可以根据具体的数据从上⾯的解析过程中进⾏数据的筛选即可,所以这⾥不演⽰如果进⾏数据的选取了(毕竟整个⽂档的内容都读取出来了:))
编辑⽂档
由于DOM解析是直接在内存中⽣成对应的⽂档树,所以我们可以很⽅便地对其进⾏编辑,这⾥演⽰修改id = 123的⼦元素name的值为Huanfeng.Xu,具体代码如下所⽰:
public void modify(){
try {
// ⽣成⽂档树的过程同前⾯所⽰,这⾥不进⾏过多的解释
File file = new File("d:/l");
DocumentBuilderFactory factory = wInstance();
DocumentBuilder builder = wDocumentBuilder();
Document document = builder.parse(file);
Element rootElement = DocumentElement();
NodeList students = ChildNodes();
for (int i = 0; i < Length(); i++){
Node tmp = students.item(i);
if (NodeType() == Node.ELEMENT_NODE){
Element element = (Element)tmp;
// 获得id为123的student节点
String attr = Attribute("id");
if ("123".equalsIgnoreCase(attr)){
NodeList childNodes = ChildNodes();
for (int j = 0; j < Length(); j++){
Node childNode = childNodes.item(j);
if (NodeType() == Node.ELEMENT_NODE) {
Element childElement = (Element) childNode;
// 修改⼦节点name的值
if (NodeName().equalsIgnoreCase("name")) {
childElement.setTextContent("Huanfeng.Xu");
break;
}
}
}
}
}
}
// 获得Transformer对象,⽤于输出⽂档
TransformerFactory transformerFactory = wInstance(); Transformer transformer = wTransformer();
// 封装成DOMResource对象
DOMSource domSource = new DOMSource(document);
Result result = new StreamResult("d:/l");
// 输出结果
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (TransformerConfigurationException e) {
e.printStackTrace();
} catch (TransformerException e) {
e.printStackTrace();
}
}
可以看到,基本的操作跟解析⽂档是⼀致的,这也⾮常好理解,修改嘛,肯定先要解析⽂档然后获得需要修改的节点信息,这⾥同样可以对节点进⾏删除、增加操作,原理同上,这⾥就不进⾏演⽰。
SAX解析
关于SAX解析的原理,这⾥就不再做过多的解释,同上⾯DOM的解析⼀样,这⾥我们直接通过代码来查看具体的操作过程
解析⽂档
/**
* 由于SAX解析是基于事件机制的,也就是当遇到指定元素的时候,解析器就会⾃动调⽤
* 回调函数,所以使⽤SAX解析的时候,需要创建⾃定义的Handler并且继承⾃DefaultHandler
* 并且将其传给解析器,⽤于指定需要进⾏回调的内容
*/
class SAXHandler extends DefaultHandler{
/**
* ⽤于标志是否已经读取到指定的元素
*/
private boolean isName;
private boolean isAge;
private boolean isGender;
@Override
public void startDocument() throws SAXException {
System.out.println("Starting parse the document");
}
@Override
public void endDocument() throws SAXException {
System.out.println("Ending parse the document");
}
dom4j读取xml@Override
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论