XML值可扩展标记语言,是用来传输和存储数据的。
XMl的特定:
XMl文档必须包含根元素。该元素是所有其他元素的父元素。XML文档中的元素形成了一颗文档树,树中的每个元素都可存在子元素。
所有XML元素都必须有关闭标签。
XML标签对大小写敏感,并且所有属性值date都需加引号。
XML元素:
XMl元素是只从包括开始标签到结束标签的部分,元素可包含其他元素、文本或两者都包含,也可拥有属性。
XML解析
基础方法:DOM、SAX
DOM解析:平台无关的官方解析方式
SAX解析:Java中基于事件驱动的解析方式
扩展方法:JDOM、DOM4J (在基础方法上扩展的,只有Java能够使用的解析方式)
1.DOM解析
优点:
·形成了树结构,直观好理解
·解析过程中树结构保留在内存中方便修改
缺点:
·当xml文件较大时,对内存消耗比较大,容易影响解析性能,并造成内存溢出
import org.w3c.dom.*;importjavax.xml.parsers.DocumentBuilder;importjavax.xml.parsers.DocumentBuilderFactory;importjava.util.LinkedList;importjava.util.List;/*** DOM 解析xml*/
public classDOM {public static void main(String[] args) throwsException {//1.创建 DocumentBuilderFactory 对象
DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();//2.通过 DocumentBuilderFactory对象创建 DocumentBuilder对象
DocumentBuilder db =dbf.newDocumentBuilder();//3.使用 DocumentBuilder对象来加载xml
Document document = db.parse("bean.xml");
System.out.println("----------------- DOM开始解析 xml -----------------");//获取 xml 文件的根节点
Element element =document.getDocumentElement();
getNoeMsg(element);
System.out.println("\n\n----------------- DOM结束解析 xml -----------------");
}/*** 获取Node节点信息
*@paramnode*/
public static voidgetNoeMsg(Node node){if(node.getNodeType() ==Node.ELEMENT_NODE){
System.out.print("
getNodeAttrs(node);
System.out.print(">\n");
NodeList nodeList=node.getChildNodes();//筛选出节点类型为ELEMENT_NODE 的节点
List list =getNodeList(nodeList);
Node childNode;int len =list.size();if(len == 0){
System.out.print(node.getTextContent()+ "\n");
}else{for (int i = 0; i < len; i++){if(list.get(i).getNodeType() ==Node.ELEMENT_NODE){
childNode=list.get(i);
getNoeMsg(childNode);
}
}
}
System.out.println("" + node.getNodeName() + ">");
}
}/*** 获取Node节点的属性信息
*@paramnode*/
public static voidgetNodeAttrs(Node node){
NamedNodeMap attrs=node.getAttributes();
Node attr;if(attrs.getLength() != 0){for (int i = 0, len = attrs.getLength(); i < len; i++){
attr=attrs.item(i);
System.out.print(" " + attr.getNodeName() + "='");
System.out.print(attr.getNodeValue()+ "'");
}
}
}/*** 筛选出节点类型为ELEMENT_NODE 的节点
*@paramnodeList
*@return
*/
public static ListgetNodeList(NodeList nodeList){
List list = new LinkedList<>();for (int i = 0,len = nodeList.getLength(); i < len; i++){if(nodeList.item(i).getNodeType() ==Node.ELEMENT_NODE){
list.add(nodeList.item(i));
}
}returnlist;
}
}
2.SAX解析
优点:
·采用事件驱动模式,对内存消耗比较小
·适用于只需处理xml中数据时
缺点:
·不易编码
·很难同时访问同一个xml中的多处不同数据
importorg.xml.sax.Attributes;importorg.xml.sax.SAXException;importorg.xml.sax.helpers.DefaultHandler;importjavax.xml.parsers.SAXParser;importjavax.xml.parsers.SAXParserFactory;public classSAX {public static void main(String[] args) throwsException {//1.创建SAXParserFactory对象
SAXParserFactory saxParserFactory =SAXParserFactory.newInstance();//2.通过SAXParserFactory对象创建 SAXParser
SAXParser saxParser =saxParserFactory.newSAXParser();//3.通过SAXParser加载xml,并传入 DefaultHandler 类型的对象进行解析
saxParser.parse("bean.xml", newSAXParserHandler());
}static class SAXParserHandler extendsDefaultHandler{/*** 解析xml开始执行方法
*@throwsSAXException*/@Overridepublic void startDocument() throwsSAXException {super.startDocument();
System.out.print("============= SAX开始解析xml =============\n");
}/*** 解析xml结束执行方法
*@throwsSAXException*/@Overridepublic void endDocument() throwsSAXException {super.endDocument();
System.out.print("\n============= SAX结束解析xml =============");
}/*** 解析节点开始执行方法
*@paramuri
*@paramlocalName
*@paramqName
*@paramattributes
*@throwsSAXException*/@Overridepublic void startElement(String uri, String localName, String qName, Attributes attributes) throwsSAXException {super.startElement(uri, localName, qName, attributes);
System.out.print("
System.out.print(" " + attributes.getQName(i) + "='");
System.out.print(attributes.getValue(i)+ "'");
}
System.out.print(">");
}/*** 解析节点结束执行方法
*@paramuri
*@paramlocalName
*@paramqName
*@throwsSAXException*/@Overridepublic void endElement(String uri, String localName, String qName) throwsSAXException {super.endElement(uri, localName, qName);
System.out.print("" + qName + ">");
}
@Overridepublic void characters(char[] ch, int start, int length) throwsSAXException {super.characters(ch, start, length);
String str= newString(ch, start, length);
System.out.print(str);
}
}
}
3.JDOM解析
特征:
·使用了具体类,不使用接口。
·API大量使用了Collections类,源码开源
importorg.jdom.Attribute;importorg.jdom.Document;importorg.jdom.Element;importorg.jdom.JDOMException;importorg.jdom.input.SAXBuilder;importjava.io.FileInputStream;importjava.io.FileNotFoundException;importjava.io.IOException;importjava.io.InputStream;importjava.util.List;/***
*
* org.jdom
* jdom
* 1.1
* */
public classJDOM {public static void main(String[] args) throwsIOException, JDOMException {//1.创建SAXBuilder对象
SAXBuilder saxBuilder = newSAXBuilder();//2.获取xml文件输入流
InputStream in = new FileInputStream("bean.xml");//3.通过SAXBuilder对象的build方法,将xml文件输入流添加到SAXBuilder对象中
Document document =saxBuilder.build(in);//4.获取xml根节点
Element rootElement =document.getRootElement();//5.根据根节点解析xml
printNodeMsg(rootElement);
}public static voidprintNodeMsg(Element element){
System.out.print("
printAttrmsg(element);
System.out.print(">\n");
List elements =element.getChildren();for(Element e : elements){if(e.getChildren().size() > 0){
printNodeMsg(e);
}else{
System.out.print("
printAttrmsg(e);
System.out.print(">");
System.out.print(e.getValue());
System.out.print("" + e.getName() + ">\n");
}
}
System.out.print("" + element.getName() + ">\n");
}/*** 获取节点的属性
*@paramelement*/
public static voidprintAttrmsg(Element element){
List attributes =element.getAttributes();for(Attribute attribute : attributes){
System.out.print(" " + attribute.getName() + "='" + attribute.getValue() + "'");
}
}
}
4.DOM4J解析
特征:
·使用了接口和抽象基本类方法
·具有性能优异、灵活性好、功能强大和极端易用的特点。
·开源
importorg.dom4j.Attribute;importorg.dom4j.Document;importorg.dom4j.DocumentException;importorg.dom4j.Element;importorg.dom4j.io.SAXReader;importjava.io.FileInputStream;importjava.io.FileNotFoundException;importjava.util.Iterator;/***
*
* dom4j
* dom4j
* 1.6.1
* */
public classDOM4J {public static void main(String[] args) throwsFileNotFoundException, DocumentException {//1.创建SAXReader对象
SAXReader saxReader = newSAXReader();//2.通过SAXReader对象的read方法,加载xml输入流
Document document = saxReader.read(new FileInputStream("bean.xml"));//3.通过Document对象获取xml的根节点
Element rootElement =document.getRootElement();//4.通过根节点解析xml
printNodeMsg(rootElement);
}public static voidprintNodeMsg(Element element){
System.out.print("
printAttrmsg(element);
System.out.print(">\n");
Iterator elementIterator =element.elementIterator();
Element e;while(elementIterator.hasNext()){
e=elementIterator.next();if(e.elementIterator().hasNext()){
printNodeMsg(e);
}else{
System.out.print("
printAttrmsg(e);
System.out.print(">");
System.out.print(e.getStringValue());
System.out.print("" + e.getName() + ">\n");
}
}
System.out.print("" + element.getName() + ">\n");
}/*** 获取节点的属性
*@paramelement*/
public static voidprintAttrmsg(Element element){
Iterator attributeIterator =element.attributeIterator();
Attribute attribute;while(attributeIterator.hasNext()){
attribute=attributeIterator.next();
System.out.print(" " + attribute.getName() + "='" + attribute.getValue() + "'");
}
}
}