//利用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解析只能读取,不能实现增删改操作。