Java解析Xml

XML解析方式分为两种:DOM方式和SAX方式
DOM:Document ObjectModel,文档对象模型。这种方式是W3C推荐的处理XML的一种方式。
SAX:Simple API for XML。这种方式不是官方标准,属于开源社区XML-DEV,几乎所有的XML解析器都支持它。

一、利用Jaxp进行dom方式解析Xml
实际上是将xml中元素按照其层次关系,解析成一个个的Node节点,类似于对树的处理。通过Dom方式可以实现对xml的增删改查操作。


//利用jaxp进行Dom方式解析
public class XmlDomParser {

public static void main(String[] args) throws Exception {
// 得到解析工厂DocumentBuilderFactory
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// 得到解析器DocumentBuilder
DocumentBuilder builder = factory.newDocumentBuilder();
// 解析指定的XML文档,得到代表内存DOM树的Document对象
Document document = builder.parse("src/book.xml");
// test1(document);
// test2(document);
// test3(document);
// test4(document);
// test5(document);
// test6(document);
// test7(document);
// test8(document);
}

// 把内存中Document树写回XML文件中
public static void backToDocument(Document document) throws Exception{
TransformerFactory facotry = TransformerFactory.newInstance();
Transformer transFormer = facotry.newTransformer();
transFormer.transform(new DOMSource(document), new StreamResult(
"src/book.xml"));
}


// 1、得到某个具体的节点内容:打印第2本书的作者
public static void test1(Document document) {
// 根据标签的名称获取所有的作者元素
NodeList nodeList = document.getElementsByTagName("作者");
// 按照索引取第2个作者元素
Node node = nodeList.item(1);
// 打印该元素的文本
String name = node.getTextContent();
System.out.println(name);


}


// 2、遍历所有元素节点:打印元素的名称
public static void test2(Node node) {
// 判断当前节点是不是一个元素节点
if (node.getNodeType() == Node.ELEMENT_NODE) {
// 如果是:打印他的名称
System.out.println(node.getNodeName());
}
// 如果不是:找到他的孩子们
NodeList nodeList = node.getChildNodes();
for (int i = 0; i < nodeList.getLength(); i++) {
Node childNode = nodeList.item(i);
// 遍历孩子节点,递归
test2(childNode);
}


}


// 3、修改某个元素节点的主体内容:把第一本书的售价改为38.00元
public static void test3(Document document) throws Exception {
// 找到第一本书的售价
NodeList nodeList = document.getElementsByTagName("售价");
Node node = nodeList.item(0);
// 设置其主体内容
node.setTextContent("38.00元");
// 把内存中Document树写回XML文件中
backToDocument(document);
}


// 4、向指定元素节点中增加子元素节点:第一本中增加子元素<内部价>99.00</内部价>
public static void test4(Document document) throws Exception {
// 创建一个新的元素并设置其主体内容
Element e = document.createElement("内部价格");
e.setTextContent("99.00元");
// 找到第一本书元素
NodeList nodeList = document.getElementsByTagName("书");
Node node = nodeList.item(0);
// 把新节点挂接到第一本书上
        node.appendChild(e);
// 把内存中Document树写回XML文件中
backToDocument(document);
}


// 5、向指定元素节点上增加同级元素节点:在第一本书的售价前面增加批发价
public static void test5(Document document) throws Exception {
// 创建一个新的元素并设置其中的主体内容
        Element e = document.createElement("批发价");
        e.setTextContent("55.00元");
// 找到第一本书的售价
        Node node = document.getElementsByTagName("售价").item(0);
// 在售价的前面加入新建的元素:增加子元素一定要使用父元素来做
        node.getParentNode().insertBefore(e, node);
// 把内存中Documeng树写回XML文件中
backToDocument(document);
}


// 6、删除指定元素节点:删除内部价格
public static void test6(Document document) throws Exception {
// 找到内部价格节点,用父节点删除
        NodeList nodeList = document.getElementsByTagName("内部价格");
        /*
         * 注意事项:
         * 1、删除多个元素节点时,由于每删除一个节点,nodeList的长度都会自动减1,
         *      如果写成for(int i=0;i<nodeList.getLength();i++),
         *      最后一个元素节点将无法删除,
         *      因此,必须将nodeList.getLength()赋值给len进行保存
         * 2、由于每次删除元素节点后,nodeList的第二个元素变成第一个
         *       因此每次删除的都应该是第一个元素,而并不是nodeList.item(i)
         */
        int len = nodeList.getLength();
        for(int i=0;i<len;i++){
        Node node = nodeList.item(0);
        node.getParentNode().removeChild(node);
        }
// 把内存中Documeng树写回XML文件中
backToDocument(document);
}


// 7、操作XML文件属性:打印第一本书的出版社
public static void test7(Document document) throws Exception {
// 得到第一本书
        NodeList nodeList = document.getElementsByTagName("书");
        Node node = nodeList.item(0);
// 打印指定属性的取值
//        NamedNodeMap nodeMap = node.getAttributes();
//        System.out.println(nodeMap.getNamedItem("出版社"));
        
        Element e = (Element) node;
System.out.println(e.getAttribute("出版社"));
}


// 8、添加一个出版社属性给第二本书
public static void test8(Document document) throws Exception {
// 得到第二本书
        Node node = document.getElementsByTagName("书").item(1);
// 打印指定属性的取值
        Element e = (Element) node;
        e.setAttribute("出版社", "上海");
// 把内存中Documeng树写回XML文件中
backToDocument(document);
}
}


二、利用Jaxp进行Sax方式解析Xml

使用Dom解析xml文档时,需要读取整个xml文档,如果xml文档特别大,就会消耗计算机的大量内存,并且容易导致内存溢出。而使用SAX解析时不必等到整个文档装载完才会对文档进行操作,但是Sax解析只能读取,不能实现增删改操作。


// 得到解析工厂SAXParserFactory
SAXParserFactory factory = SAXParserFactory.newInstance();
// 得到解析器SAXParser
SAXParser parser = factory.newSAXParser();
// 得到XML读取器:XMLReader
XMLReader reader = parser.getXMLReader();
// 注册内容处理器:ContentHandler
reader.setContentHandler(new MyContentHandler());
// 读取XML文档
reader.parse("src/book.xml");

class MyContentHandler implements ContentHandler{
//重写相关方法
//解析到文档开始时被调用
public void startDocument() throws SAXException {
System.out.println("解析到了文档的开始");
}
//解析到元素开始时被调用:qName元素名称
public void startElement(String uri, String localName, String qName,
Attributes atts) throws SAXException {
System.out.println("解析到了元素的开始:"+qName);
}
//解析到文本内容时被调用
public void characters(char[] ch, int start, int length)
throws SAXException {
System.out.println("文本内容:"+new String(ch,start,length));
}
//解析到元素结束时被调用
public void endElement(String uri, String localName, String qName)
throws SAXException {
System.out.println("解析到了元素的结束:"+qName);
}
//解析到文档结束时被调用
public void endDocument() throws SAXException {
System.out.println("解析到了文档的结束");
}
}


三、利用Dom4j解析xml
public class Dom4jDemo {


public static void main(String[] args) throws Exception {
// 解析xml文档获取一个dom4j的document对象
SAXReader reader = new SAXReader();
Document doc = reader.read("src/book.xml");
// test1(doc);
// test2(doc);
// test3(doc);
// test4(doc);
// test5(doc);
// test6(doc);
// test7(doc);
test8(doc);


}


// 1、得到某个具体的节点内容:第2本书的作者
public static void test1(Document doc) throws Exception {
// 得到根元素
Element rootElement = doc.getRootElement();
// 得到第二本书的作者
List<Element> bookList = rootElement.elements("书");
Element book = bookList.get(1);
Element author = book.element("作者");
// 打印作者
System.out.println(author.getText());
}


// 2、遍历所有元素节点:
public static void test2(Document doc) throws Exception {
Element rootElement = doc.getRootElement();
treeWalk(rootElement);
}


private static void treeWalk(Element rootElement) {
// TODO Auto-generated method stub
System.out.println(rootElement.getName());
List<Element> elements = rootElement.elements();
// 遍历所有的元素,打印他的名称
for (Element e : elements) {
treeWalk(e);
}
}


// 3、修改某个元素节点的主体内容:修改第2本书的售价
public static void test3(Document doc) throws Exception {
// 获取根元素
Element rootElement = doc.getRootElement();
// 得到第二本书售价
List<Element> bookList = rootElement.elements("书");
Element secondBook = bookList.get(1);
Element price = secondBook.element("售价");
// 修改售价
price.setText("99.00 元");
// 写回xml
backToXml(doc);
}


private static void backToXml(Document doc) throws Exception {
OutputStream out = new FileOutputStream("src/book.xml");
OutputFormat format = OutputFormat.createCompactFormat();
// 指定编码,不然乱码
format.setEncoding("utf-8");
XMLWriter writer = new XMLWriter(out, format);
writer.write(doc);
}


// 4、向指定元素节点中增加子元素节点:给第1本书添加批发价
public static void test4(Document doc) throws Exception {
// 获取根元素
Element rootElement = doc.getRootElement();
// 获取第一本书
Element e = (Element) rootElement.elements("书").get(0);
// 增加批发价
e.addElement("批发价").setText("50.00 元");
;
// 重写xml
backToXml(doc);
}


// 5、向指定元素节点上增加同级元素节点:在第一本书的售价前面添加内部价
public static void test5(Document doc) throws Exception {
// 通过根元素获取第一本书
Element rootElement = doc.getRootElement();
Element book = (Element) rootElement.elements("书").get(0);
// 借助DocumentHelper创建内部价元素
Element price = DocumentHelper.createElement("内部价");
price.setText("70.00 元");
// 获得第一本书的内部元素
List<Element> e = book.elements();
// 在第三个元素位置插入“内部价”元素
e.add(2, price);
// 重写xml
backToXml(doc);
}


// 6、删除指定元素节点:删除批发价
public static void test6(Document doc) throws Exception {
List<Element> bookList = doc.getRootElement().elements("书");
for (Element e : bookList) {
e.remove(e.element("批发价"));
}
backToXml(doc);
}


// 7、操作XML文件属性:第1本书添加一个出版社属性
public static void test7(Document doc) throws Exception {
List<Element> bookList = doc.getRootElement().elements("书");
Element firstBook = bookList.get(0);
firstBook.addAttribute("出版社", "南京");
backToXml(doc);
}


// 获取第一本书的出版社属性值
public static void test8(Document doc) throws Exception {
List<Element> bookList = doc.getRootElement().elements();
Element firstBook = bookList.get(0);
String value = firstBook.attributeValue("出版社");
System.out.println(value);
}
}

你可能感兴趣的:(java,dom4j,xml解析,jaxp)