XML:EXtensible Markup Language 可扩展标记语言,主要用于数据的传输与共享,由于其传输与共享数据简单那的这一特性,广泛用于互联网等数据的传输,以及一些框架软件的配置文件.相对于HTML的语法相对松散的特性,XML的语法十分严谨。XML的验证主要通过DTD文件或者Schema文件。(具体baidu或google)
Java解析XML 提供了四种解析方式,每一种方式都有其特点。
首先是想xml.xml文件
<?xml version="1.0" encoding="gbk"?> <books> <book> <bookName>《三国》</bookName> <author>罗贯中</author> </book> <book> <bookName>《西游记》</bookName> <author>吴承恩</author> </book> <book> <bookName>《水浒》</bookName> <author>施耐庵</author> </book> </books>
第一种:使用DOM的方式解析XML。
DOM是用与平台和语言无关的方式表示XML的官方W3C标准。使用DOM方式能十分方便的解析小型XML文档。其原理是一次性加载整个XML文档到内存,在内存中组织成树形结构,并通过节点与节点的联系来解析XML文档,因而DOM也被认为是基于对象获树的。其特点是简单易学,整个树在内存中是持久的,因而可以它支持以便应用程序能对数据或结构进行修改。但正因为起一次性加载整个文档,其所占用的内存比较大,对内存要求比较高。
public static void main(String[] args) { System.out.println("Hello,world!"); String fileName = "D://java/xml/xml.xml"; File file = new File(fileName); XMLDemo xmlDemo = new XMLDemo(); try { xmlDemo.parseXMLByDOM(file); } catch (Exception e) { // TODO: handle exceptio e.printStackTrace(); } } //通过DOM的方式解析XML文件 public void parseXMLByDOM(File file)throws Exception{ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse(file); NodeList nodeList = doc.getElementsByTagName("book"); for (int i = 0; i < nodeList.getLength(); i++) { String book = doc.getElementsByTagName("bookName").item(i).getFirstChild().getNodeValue(); String author = doc.getElementsByTagName("author").item(i).getFirstChild().getNodeValue(); System.out.println(book+"的作者是:"+author); } }
具体是因为xml文件申明的编码格式与xml文件保存时的编码格式不一致所造成的,因此,有可能encoding=gbk也是会出错的关键在与你电脑保存的编码格式。
第二种SAX解析XML方式
可以说SAX是基于事件的XML解析方式,SAX解析器在解析XML输入的构件时就报告事件,但不会和DOM那样存储文档,有时间来决定是否构件数据结构。在SAX解析时,需要一个处理器来定义不同的解析器事件的时间动作。ContentHandler定义了一下毁掉方法:
StartDocuemnt与endDocument 文档开始或结束时使用一次 startElement与endElement 遇到起始或结束标签时调用 characters遇到字符数据时使用.
SAX 解析DEMO如下:
public static void main(String[] args) { System.out.println("Hello,world!"); String fileName = "D://java/xml/xml.xml"; File file = new File(fileName); XMLDemo xmlDemo = new XMLDemo(); try { // xmlDemo.parseXMLByDOM(file); xmlDemo.parseXMLBySAX(file); } catch (Exception e) { // TODO: handle exceptio e.printStackTrace(); } } private void parseXMLBySAX(File file) throws Exception { SAXParserFactory spf = SAXParserFactory.newInstance(); SAXParser saxParser = spf.newSAXParser(); saxParser.parse(file, new PraseXML()); } public class PraseXML extends DefaultHandler { private Vector<String> tagName; private Vector<String> tagValue; private int step; // 开始解析XML文件 public void startDocument() throws SAXException { tagName = new Vector<String>(); tagValue = new Vector<String>(); step = 0; } // 结束解析XML文件 public void endDocument() throws SAXException { for (int i = 0; i < tagName.size(); i++) { if (!tagName.get(i).equals("") || tagName.get(i) != null) { System.out.println("节点名称:" + tagName.get(i)); System.out.println("节点值:" + tagValue.get(i)); } } } public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { // 节点名称 tagName.add(qName); // 循环输出属性 for (int i = 0; i < attributes.getLength(); i++) { // 获取属性名称 System.out.println("属性名称:" + attributes.getQName(i)); // 获取属性值 System.out.println("属性值:" + attributes.getValue(attributes.getQName(i))); } } /** * 在遇到结束标签时调用此方法 */ public void endElement(String uri, String localName, String qName) throws SAXException { step = step + 1; } /** * 读取标签里的值,ch用来存放某行的xml的字符数据,包括标签,初始大小是2048, 每解释到新的字符会把它添加到char[]里。 * * 注意,这个char字符会自己管理存储的字符, 并不是每一行就会刷新一次char,start,length是由xml的元素数据确定的, * 暂时找不到规律,以后看源代码. * * 这里一个正标签,反标签都会被执行一次characters,所以在反标签时不用获得其中的值 */ public void characters(char ch[], int start, int length) throws SAXException { // 只要当前的标签组的长度一至,值就不赋,则反标签不被计划在内 if (tagName.size() - 1 == tagValue.size()) { tagValue.add(new String(ch, start, length)); } } public Vector getTagName() { return tagName; } public void setTagName(Vector tagName) { this.tagName = tagName; } public Vector getTagValue() { return tagValue; } public void setTagValue(Vector tagValue) { this.tagValue = tagValue; } }
第四种DOM4J