XML解析方式分为两种:DOM和SAX
DOM:(Document Object Model,即文档对象模型),是有W3C组织推荐的处理XML的一种方式
SAX:(Simple API for XML)不是官方标准,但是它是XML社区事实上的标准,几乎所有的XML解析器都支持它。
2>DOM(使用javax.xml.*):该方式会得到并维护XML文档的DOM树,所以你可以直接对该对象进行处理。
(1).读取XML文档实例
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse("src/com/xml/dom.xml");//path为文档路径
(2)./** 遍历文档(只打印出标签名) */
public void list(Node node){//Document也是一个Node
if(node.getNodeType() == Node.ELEMENT_NODE){
System.out.println(node.getNodeName());//当前节点名称
}
NamedNodeMap attMap = node.getAttributes();
for(int i=0;attMap!=null && i<attMap.getLength();i++){//节点的属性不属于节点的孩子
Node att = attMap.item(i);//属性也是节点
System.out.println(att.getNodeName()+"="+att.getNodeValue());
}
NodeList list = node.getChildNodes();
for(int i=0;i<list.getLength();i++){
Node chiled = list.item(i);
list(chiled);//这里注意递归
}
}
(3).读取当前节点下的特定节点
public void read(Document node,String wantFind){
Node title = node.getElementsByTagName("wantFind").item(0);
System.out.println(title.getTextContent());//文本内容
System.out.println(author.getAttribute("name"));//属性
}
(4).添加节点
public void add(Document node) throws Exception{
//首先创造节点
Element aa = node.createElement("aaa");//<aaa>000</aaa>
aa.setTextContent("000");
//将节点挂载到想要被添加的节点
Element root = (Element)node.getElementsByTagName("root").item(0);
root.appendChild(aa);
//root.insertBefore(aa,node.getElementsByTagName("body").item(0));在body之前插入了文档
//只做到这步,也只是写入到内存中了,并没有反应到文档中去
//通过下面的更新文档方法进行文档的更新
}
(5).删除节点
public void delete(Document document)throws Exception{
//这是由父找子,然后再删除子的方式
Element aaa = (Element)document.getElementsByTagName("aaa").item(0);
document.getChildNodes().item(0).removeChild(aaa);
//下面的这种更加好(子找父,然后删自己)
Node head = document.getElementsByTagName("head").item(0);
head.getParentNode().removeChild(head);
//删除属性--只要涉及到对于属性的操作,都把node节点转成element
//((Element)head).removeAttribute("");
//通过下面的更新文档方法进行文档的更新
}
(6).将文档更新
public void update(Document document) throws Exception{
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer();
transformer.transform(new DOMSource(document), new StreamResult(new File("src/com/xml/dom.xml")));
}
3>SAX(使用javax.xml.*):该方法是事件响应模式运作的,这意味着你无法得到文档整体,只能在解析特定事件触发时对特定事件做出处理。
(1).SAX加载xml文档的步骤:
//1.得到sax工厂
SAXParserFactory factory = SAXParserFactory.newInstance();
//2.通过工厂得到解析器
SAXParser parser = factory.newSAXParser();
//3.通过解析器得到一个xml文档的读取器
XMLReader reader = parser.getXMLReader();
//注册事件处理器
reader.setContentHandler(new MyContentHander());
//4.通过读取器读取xml文档
reader.parse("src/com/xml/dom.xml");
(2).对于上面的MyContentHander类的说明:
这是自己写的事件处理器,继承ContentHandler,在该类中书写你对于xml文档的业务处理。
class MyContentHander implements ContentHandler{
//解析到开始标签时的处理
@Override
public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
//以下是获取各标签头的方法,具体业务由自己把控
System.out.println("<"+qName+" ");
for(int i=0;i<atts.getLength();i++){
System.out.println(atts.getQName(i)+""+atts.getValue(i)+" ");
}
System.out.println(">");
}
//解析到结束标签时的处理
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
}
//还有好多可重载方法,请自行调查,鉴于DOM4J等工具类的存在,其实不用查了,一般不使用。
}
4>DOM4J的一般的使用:
1.首先下载DOM4J的jar包,导入到你的工程中
2.加载xml文件
(1)普通方式:(使用了new File(文件路径))
SAXReader reader = new SAXReader();
Document document = reader.read(new File("src/com/xml/dom.xml"));
Element root = document.getRootElement();
(2)类装载器方式:
SAXReader reader = new SAXReader();
//InputStream in = DOM4J.class.getClassLoader().getResourceAsStream("dom1.xml");
//上面的也还是有问题的,在再次读取文件时,可能始终得不到改后的数据
//以下的方法是最优的(通过URL对象去实现)
URL url = DOM4J.class.getClassLoader().getResource("dom1.xml");
FileInputStream in = new FileInputStream(url.getPath());
Document document = reader.read(in);
3.通过上面的方法就得到了document对象,也就是DOM树,那么增删改查就和DOM方式相同了。
4.对于DOM4J还提供了结合XPATH的快速查找方式:
root.selectSingleNode("xpath");//注意,该方法需要jaxen-1.1-beta-6.jar
5.以下是XPATH简要介绍:
/AAA:找出为AAA的元素
/AAA/BBB/DDD:找出AAA下面BBB的DDD元素
//BBB:无视层级关系,找出所有BBB元素
//DDD/BBB:找出凡是DDD下的BBB元素
/*/*/*/BBB:找出有3个祖先元素的BBB元素
/AAA/BBB[1]:找出AAA第一个BBB元素
/AAA/BBB[last()]:找出AAA下最后一个BBB子元素
//BBB[@id]:找出有id属性的BBB元素
//BBB[@name]:找出有name属性的BBB元素
//BBB[@*]:找出有任意属性的BBB元素
//BBB[@id='b1']:找出含有属性id且其值为"b1"的BBB元素
//BBB[normalize-space(@name)='bbb']:选择含有属性name且其值(用normalize-space函数去掉前后空格后)为'bbb'的元素
//*[count(BBB)=2]:选择含有2个BBB子元素的元素
如有不当,还请指正。