什么是xml:
xml是Extensible Markup Language的缩写,可扩展标记语言。
xml是一种类似Html的标记语言
xml是用来描述数据的。
xml的标记不是在xml总预定义的,而是自己定义标记。
xml使用文档类型定义DTD或者Schema来描述数据。
xml使用DTD或者Schema后就是自描述的语言。
xml不是html的替代品,两种语言的用途不同:
xml是用来描述数据的,用来存储数据。
html是用来显示数据。
首先要明确的是:XML是被设计用来存储数据、携带数据和交换数据的,他不是为了显示数据而设计的。
xml解析技术:
dom:(Document Object Model, 即文档对象模型) 是 W3C 组织推荐的处理 XML 的一种方式。
sax: (Simple API for XML) 不是官方标准,但它是 XML 社区事实上的标准,几乎所有的 XML 解析器都支持它。
xml解析器(API):
Crimson(sun:Jaxp)、Xerces(IBM:Jdom)、Aelfred2(dom4J:dom4j)
两种xml解析的优缺点:
dom:很方便对文档进行遍历,对文档的增删改查也很方便,缺点是要装载整个文档,当xml文档较大的时候,dom占用内存也较大,浪费系统资源,所以dom解析不适合大文档。
sax:解析文档速度很快,占用资源少,但sax解析只适合读取文档数据,不适合对文档进行增删改查。
sun:Jaxp:
JAXP支持两种方式(DOM和SAX)对XML文档进行解析,两种方式思路类似,都需要通过调用工厂类得方法来获得解析器,进而通过解析器对文档进行解析
package com.enterise.always.xml;
import java.io.File;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
/**
* JAXP xml解析
*
* @author Always
*
*/
public class XmlRead {
public static void redXml() throws ParserConfigurationException,
SAXException, IOException {
// 1.DocumentBuilderFactory通过工厂类获取实例
DocumentBuilderFactory documentFactory = DocumentBuilderFactory
.newInstance();
// 2.利用DocumentBuilderFactory创建DocumentBuilder
DocumentBuilder documentBuilder = documentFactory.newDocumentBuilder();
// 3.读取xml文件
File file = new File("src/info.xml");
// 4.利用DocumentBuilder得到整个文档对象
Document document = documentBuilder.parse(file);
// 5.解析文档
//获取编码和版本
String xmlEncoding = document.getXmlEncoding();
String xmlVersion = document.getXmlVersion();
//获取根节点
Element documentElement = document.getDocumentElement();
String nodeName = documentElement.getNodeName();
//获取子节点
if(documentElement.hasChildNodes()){
sysNodeList(documentElement.getChildNodes());
}
}
private static void sysNodeList(NodeList nodeList){
for(int i = 0;i<nodeList.getLength();i++){
Node node = nodeList.item(i);
System.out.println("node--->"+node.getNodeName()+"----value--->"+node.getNodeValue());
//获取参数
NamedNodeMap nodeMap = node.getAttributes();
if( nodeMap != null && nodeMap.getLength() > 0){
sysNameNodeMap(nodeMap);
}
//获取子节点
if(node.hasChildNodes()){
System.out.println("二次-----------------");
NodeList childNodes = node.getChildNodes();
sysNodeList(childNodes);
}
}
}
private static void sysNameNodeMap(NamedNodeMap nodeMap){
for (int i = 0; i < nodeMap.getLength(); i++) {
Node node = nodeMap.item(i);
System.out.println("node--2->"+node.getNodeName()+"----value-2-->"+node.getNodeValue());
//在次获取子节点
if(node.hasChildNodes()){
System.out.println("二次-----------------");
NodeList childNodes = node.getChildNodes();
sysNodeList(childNodes);
}
}
}
}
sax解析:
转载:
package com.enterise.always.xml;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
class MyContentHandler implements ContentHandler {
StringBuffer jsonStringBuffer;
int frontBlankCount = 0;
public MyContentHandler() {
jsonStringBuffer = new StringBuffer();
}
/*
* 接收字符数据的通知。 在DOM中 ch[begin:end] 相当于Text节点的节点值(nodeValue)
*/
@Override
public void characters(char[] ch, int begin, int length)
throws SAXException {
StringBuffer buffer = new StringBuffer();
for (int i = begin; i < begin + length; i++) {
switch (ch[i]) {
case '\\':
buffer.append("\\\\");
break;
case '\r':
buffer.append("\\r");
break;
case '\n':
buffer.append("\\n");
break;
case '\t':
buffer.append("\\t");
break;
case '\"':
buffer.append("\\\"");
break;
default:
buffer.append(ch[i]);
}
}
System.out.println(this.toBlankString(this.frontBlankCount)
+ ">>> characters(" + length + "): " + buffer.toString());
}
/*
* 接收文档的结尾的通知。
*/
@Override
public void endDocument() throws SAXException {
System.out.println(this.toBlankString(--this.frontBlankCount)
+ ">>> end document");
}
/*
* 接收文档的结尾的通知。 参数意义如下: uri :元素的命名空间 localName :元素的本地名称(不带前缀) qName
* :元素的限定名(带前缀)
*
*/
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
System.out.println(this.toBlankString(--this.frontBlankCount)
+ ">>> end element : " + qName + "(" + uri + ")");
}
/*
* 结束前缀 URI 范围的映射。
*/
@Override
public void endPrefixMapping(String prefix) throws SAXException {
System.out.println(this.toBlankString(--this.frontBlankCount)
+ ">>> end prefix_mapping : " + prefix);
}
/*
* 接收元素内容中可忽略的空白的通知。 参数意义如下: ch : 来自 XML 文档的字符 start : 数组中的开始位置 length :
* 从数组中读取的字符的个数
*/
@Override
public void ignorableWhitespace(char[] ch, int begin, int length)
throws SAXException {
StringBuffer buffer = new StringBuffer();
for (int i = begin; i < begin + length; i++) {
switch (ch[i]) {
case '\\':
buffer.append("\\\\");
break;
case '\r':
buffer.append("\\r");
break;
case '\n':
buffer.append("\\n");
break;
case '\t':
buffer.append("\\t");
break;
case '\"':
buffer.append("\\\"");
break;
default:
buffer.append(ch[i]);
}
}
System.out.println(this.toBlankString(this.frontBlankCount)
+ ">>> ignorable whitespace(" + length + "): "
+ buffer.toString());
}
/*
* 接收处理指令的通知。 参数意义如下: target : 处理指令目标 data : 处理指令数据,如果未提供,则为 null。
*/
@Override
public void processingInstruction(String target, String data)
throws SAXException {
System.out.println(this.toBlankString(this.frontBlankCount)
+ ">>> process instruction : (target = \"" + target
+ "\",data = \"" + data + "\")");
}
/*
* 接收用来查找 SAX 文档事件起源的对象。 参数意义如下: locator : 可以返回任何 SAX 文档事件位置的对象
*/
@Override
public void setDocumentLocator(Locator locator) {
System.out.println(this.toBlankString(this.frontBlankCount)
+ ">>> set document_locator : (lineNumber = "
+ locator.getLineNumber() + ",columnNumber = "
+ locator.getColumnNumber() + ",systemId = "
+ locator.getSystemId() + ",publicId = "
+ locator.getPublicId() + ")");
}
/*
* 接收跳过的实体的通知。 参数意义如下: name : 所跳过的实体的名称。如果它是参数实体,则名称将以 '%' 开头, 如果它是外部 DTD
* 子集,则将是字符串 "[dtd]"
*/
@Override
public void skippedEntity(String name) throws SAXException {
System.out.println(this.toBlankString(this.frontBlankCount)
+ ">>> skipped_entity : " + name);
}
/*
* 接收文档的开始的通知。
*/
@Override
public void startDocument() throws SAXException {
System.out.println(this.toBlankString(this.frontBlankCount++)
+ ">>> start document ");
}
/*
* 接收元素开始的通知。 参数意义如下: uri :元素的命名空间 localName :元素的本地名称(不带前缀) qName
* :元素的限定名(带前缀) atts :元素的属性集合
*/
@Override
public void startElement(String uri, String localName, String qName,
Attributes atts) throws SAXException {
System.out.println(this.toBlankString(this.frontBlankCount++)
+ ">>> start element : " + qName + "(" + uri + ")");
}
/*
* 开始前缀 URI 名称空间范围映射。 此事件的信息对于常规的命名空间处理并非必需: 当
* http://xml.org/sax/features/namespaces 功能为 true(默认)时, SAX XML
* 读取器将自动替换元素和属性名称的前缀。 参数意义如下: prefix :前缀 uri :命名空间
*/
@Override
public void startPrefixMapping(String prefix, String uri)
throws SAXException {
System.out.println(this.toBlankString(this.frontBlankCount++)
+ ">>> start prefix_mapping : xmlns:" + prefix + " = " + "\""
+ uri + "\"");
}
private String toBlankString(int count) {
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < count; i++)
buffer.append(" ");
return buffer.toString();
}
}
package com.enterise.always.xml;
import java.io.FileNotFoundException;
import java.io.IOException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
public class SaxRead {
/**
* sax解析xml的优势:
* 优点:解析文件速度快,占用内存少
* 缺点:适合对文档的解析,不适合对文档进行增删改
* @throws SAXException
* @throws ParserConfigurationException
* @throws IOException
* @throws FileNotFoundException
*/
public static void readXmlBySax() throws ParserConfigurationException, SAXException, FileNotFoundException, IOException{
//解析工厂
SAXParserFactory parseFactory = SAXParserFactory.newInstance();
//解析器
SAXParser saxParse = parseFactory.newSAXParser();
XMLReader xmlReader = saxParse.getXMLReader();
//处理器
// MyDefaultHandler handler = new MyDefaultHandler();
MyContentHandler handler = new MyContentHandler();
xmlReader.setContentHandler(handler);
xmlReader.parse("src/info.xml");
}
}
dom4j遍历:
package com.enterise.always.xml;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Iterator;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
/**
* dom4j解析xml
*
* @author Always
*
*/
public class DomRead {
public static void dom4jRead() throws FileNotFoundException,
DocumentException {
SAXReader reader = new SAXReader();
Document document = reader.read(new FileInputStream("src/book.xml"));
// 获取根节点
Element element = document.getRootElement();
// 1.遍历整个文档
listElement(element);
}
/**
* 每个节点都是element 遍历整个文档
*
* @param element
*/
@SuppressWarnings("unchecked")
private static void listElement(Element element) {
// 迭代整个element
Iterator iterator = element.elementIterator();
while (iterator.hasNext()) {
Element childElement = (Element) iterator.next();
// 获取节点名称
System.out.println("childElement----->" + childElement.getName());
// 获取<name>Thinking in JAVA</name>--》text:Thinking in JAVA
String childText = element.element(childElement.getName())
.getText();
if (childText != null) {
System.out.println("childText-------------->" + childText);
}
if (childElement.elementIterator().hasNext()) {
listElement(childElement);
}
}
}
}