JAVA中XML的解析

DOM解析

JAVA提供的默认解析XML文档的方式, 实现了w3c中的标准, 应用最广泛.

dom是个功能强大的解析工具,适用于小文档. 它会把整篇xml文档装载进内存中,形成一颗文档对象树

简单使用

/**
 * DOM解析测试类
 *
 * @author jssd
 * Create 2019-07-10 18:31
 */
public class Test {
	public static void main(String[] args) {
		// 1. 取得文档建立工厂
		DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
		// 2. 获取文档建立对象
		DocumentBuilder documentBuilder;
		try {
			documentBuilder = documentBuilderFactory.newDocumentBuilder();
			// 3. 通过文档建立对象取得文档对象
			Document document = documentBuilder.parse("books.xml");
			// 4. 通过元素名, 取得元素对象
			NodeList noteList = document.getElementsByTagName("books");
			// 查看取得元素对象个数
			System.out.println("根元素个数" + noteList.getLength());
			System.out.println("====================查看元素属性======================");
			for (int i = 0; i < noteList.getLength(); i++) {
				// 取得单个对象
				Node item = noteList.item(i);
				// 取得所有属性
				NamedNodeMap attributes = item.getAttributes();
				// 循环遍历所有属性, 并输出
				System.out.println(item.getNodeName() + "节点的所有属性如下: ");
				for (int j = 0; j < attributes.getLength(); j++) {
					Node node = attributes.item(j);
					System.out.println(node.getNodeName() + ": " + node.getNodeValue());
				}
				System.out.println("=============查看元素内节点或文本内容============");
				// 取得所有子元素节点
				NodeList childNodes = item.getChildNodes();
				System.out.println("childNodes.getLength() = " + childNodes.getLength());
				/*
				DOM解析的过程中, 可以看到字节点中有空的文本节点, 我们查看的时候需要过滤出来
				 */
				for (int j = 0; j < childNodes.getLength(); j++) {
					Node node = childNodes.item(j);
					if (node.getNodeType() == Node.ELEMENT_NODE) {
						// 查看节点名和节点值
						System.out.println("childNodes.item(j) = " + node.getNodeName() + ":" + node.getNodeValue());
					}
				}
			}
			
		} catch (ParserConfigurationException | SAXException | IOException e) {
			e.printStackTrace();
		}
	}
}

SAX解析

和DOM一样, 同样是JAVA原生组件, 全称是simple API for XML

SAX 是一种以事件驱动的XML API, SAX去DOM不同的是它边扫描边解析, 自顶向下依次解析, 由于边扫描边解析, 所以它解析XML具有速度快, 占用内存少的优点

简单使用:

/**
 * @author jssd
 * Create 2019-07-10 19:14
 */
public class Test {
   public static void main(String[] args) {
      // 1. 取得SAX解析器工厂
      SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
      // 2. 从sax解析器工厂中取得解析器
      SAXParser saxParser;
      try {
         saxParser = saxParserFactory.newSAXParser();
         // 3. 重写DefaultHandler类, 使用DefaultHandler类中的方法, 解析XML
         BookHandler bookHandler = new BookHandler();
         // 4. 开始解析
         saxParser.parse(new File("books.xml"), bookHandler);
      } catch (ParserConfigurationException | SAXException | IOException e) {
         e.printStackTrace();
      }
   }
}

使用SAX的时候, 需要有个类继承DefaultHandler

/**
 * @author jssd
 * Create 2019-07-10 19:19
 */
public class BookHandler extends DefaultHandler {
   // 文档开始解析的时候调用
   @Override
   public void startDocument() throws SAXException {
      super.startDocument();
      System.out.println("文档开始解析");
   }

   // 文档解析结束的时候调用
   @Override
   public void endDocument() throws SAXException {
      super.endDocument();
      System.out.println("文档解析结束");
   }

   // 元素开始解析的时候调用
   @Override
   public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
      super.startElement(uri, localName, qName, attributes);
      System.out.println("元素属性: ");
      if (attributes.getLength() != 0) {
         for (int i = 0; i < attributes.getLength(); i++) {
            System.out.println("attributes.getQName() + attributes.getValue() = " +
                  attributes.getQName(i) + ": " + attributes.getValue(i));
         }
      }
      System.out.println("元素名: " + qName);
   }

   // 元素解析结束的时候调用
   @Override
   public void endElement(String uri, String localName, String qName) throws SAXException {
      super.endElement(uri, localName, qName);
   }

   // 解析XML中的文本时候调用
   @Override
   public void characters(char[] ch, int start, int length) throws SAXException {
      super.characters(ch, start, length);
      String str = new String(ch, start, length);
      if(!"".equals(str.trim())) { // 过滤空的文本节点
         System.out.println("文本内容为: " + str);
      }
   }
}

JDOM解析

JDOM是第三方插件, 不属于JAVA原生解析方式, 所以需要导入jar包

它基于树型结构,利用纯 Java 的技术对 XML 文档实现解析。所以只适合于 Java
语言

简单步骤:

  1. 创建一个SAXBuilder 对象
  2. 调用SAXBuilder对象的build方法, 得到Document对象(通过IO流)
  3. 获取根节点
  4. 获取根节点的直接子节点的集合
  5. 遍历集合

简单使用:
注意: 使用的时候导包不要导错了

/**
 * JDom 学习测试类
 * @author jssd
 * Create 2019-07-11 14:01
 */
public class Test {
	public static void main(String[] args) {
		// 取得SAXBuilder对象
		SAXBuilder saxBuilder = new SAXBuilder();
		try {
			// 取得整个文档
			Document document = saxBuilder.build("books.xml");
			// 从文档中取得根节点
			Element rootElement = document.getRootElement();
			// 从根节点中取出子节点
			List children = rootElement.getChildren();
			for (Object child : children) {
				Element element = (Element) child;
				// 查看子节点的属性
				List attributes = element.getAttributes();
				for (Object attribute : attributes) {
					Attribute att = (Attribute) attribute;
					System.out.println("att.getName = " + att.getName() + ", att.getValue = " + att.getValue());
				}
			}

			// 查看子节点的内容
			for (Object child : children) {
				Element element = (Element) child;
				List subChild = element.getChildren();
				for (Object o : subChild) {
					Element subEle = (Element)o;
					System.out.println("subEle.getName() = " + subEle.getName());
					System.out.println("subEle.getValue() = " + subEle.getValue());
				}
			}

		} catch (JDOMException | IOException e) {
			e.printStackTrace();
		}
	}
}

dom4j解析

DOM4J 是一个 Java 的 XML API, 是 JDOM 的升级品,用来读写 XML 文件的

解析步骤:

  1. 创建SAXReader对象
  2. 调用read方法
  3. 过去根元素
  4. 通过迭代器遍历直接节点

简单使用:

/**
 * @author jssd
 * Create 2019-07-11 14:31
 */
public class Test {
	public static void main(String[] args) {
		SAXReader saxReader = new SAXReader();
		try {
			// 取得文档
			Document document = saxReader.read("books.xml");
			// 取得根元素
			Element rootElement = document.getRootElement();
			// 取得根元素之下的子元素
			for (Iterator iter = rootElement.elementIterator(); iter.hasNext(); ) {
				Element bookEle = (Element) iter.next();
				// 获取子元素的属性
				for (Iterator iterator = bookEle.attributeIterator(); iterator.hasNext(); ) {
					Attribute bookAttr = (Attribute) iterator.next();
					System.out.println("属性的名字: " + bookAttr.getName() + ", 属性的值: " + bookAttr.getValue());
				}

				for (Iterator iterator = bookEle.elementIterator(); iterator.hasNext(); ) {
					Element element = (Element) iterator.next();
					System.out.println("子节点的值: " + element.getName() + ", 子节点的值: " + element.getText());
				}
			}
		} catch (DocumentException e) {
			e.printStackTrace();
		}
	}
}

四种解析方式比较

  1. DOM解析

    形成了树的结构, 有助于更好的理解, 掌握, 且代码容易编写. 解析过程中, 树结构保存在内存中, 方便修改

  2. SAX解析

    采用事件驱动模式, 对内存的耗费比较小. 适用于只处理XML文件中的数据时

  3. JDOM解析

    仅使用具体类, 而不使用接口, API大量使用了Collections类

  4. DOM4J解析

    JDOM的一种只能分支, 它合并了许多超出基本XML文档表示的功能. 它使用接口和抽象基本类方法. 具有性能优异, 灵活性好, 功能强大和极端易用的特点. 开源.

DOM4J配合XPATH快速选择一个元素

我们使用DOM4J解析XML的时候, 有的时候元素层数比较多, 难道要一个一个元素的取得进去吗? 显然, XML层数多了之后, 就不现实了. 所以我们有了XPATH技术.

XPath即为XML路径语言,它是一种用来确定XML(标准通用标记语言的子集)文档中某部分位置的语言。XPath基于XML的树状结构,提供在数据结构树中找寻节点的能力。起初 XPath 的提出的初衷是将其作为一个通用的、介于XPointer与XSLT间的语法模型。但是 XPath 很快的被开发者采用来当作小型查询语言。

小知识: 使用chrome浏览器打开一个网页的时候, 按f12 查看源代码, 右键网页中html元素, 可以copyXpath

简单使用:

假如我有一个XML如下

<?xml version="1.0" encoding="utf-8" ?>
<books xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:noNamespaceSchemaLocation="books.xsd">
    <book id="1111">
        <name>java 实战开发</name>
        <author>jssd</author>
        <price>1000</price>
    </book>
    <book id="1001">
        <name>java开发实战</name>
        <author>张小三</author>
        <price>98.5</price>
    </book>
</books>

查找指定元素:

public class Test {
	public static void main(String[] args) {
		// 获取DOM4J中的SAXReader对象
		SAXReader saxReader = new SAXReader();
		Document read;
		try {
			// 读取整个文档
			read = saxReader.read("books.xml");
			// 我想要选中id=1001中book的author节点
			Node node = read.selectSingleNode("//book[@id=1001]/author");
			System.out.println("node.getName() + \", \" + node.getText() = " + node.getName() + ", " + node.getText());
		} catch (DocumentException e) {
			e.printStackTrace();
		}
	}
}

XPath使用非常简单, 就是配合DOM4J进行选择节点, 关于XPath语法, 本文不做介绍, 请查阅相关API

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
package com.hexiang.utils; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; /** * 本类是专门解析XML文件的,主要用于为系统读取自己的配置文件时提供最方便的解析操作 * @author HX * */ public class XmlManager { /** * 得到某节点下某个属性的值 * @param element 要获取属性的节点 * @param attributeName 要取值的属性名称 * @return 要获取的属性的值 * @author HX_2010-01-12 */ public static String getAttribute( Element element, String attributeName ) { return element.getAttribute( attributeName ); } /** * 获取指定节点下的文本 * @param element 要获取文本的节点 * @return 指定节点下的文本 * @author HX_2010-01-12 */ public static String getText( Element element ) { return element.getFirstChild().getNodeValue(); } /** * 解析某个xml文件,并在内存创建DOM树 * @param xmlFile 要解析XML文件 * @return 解析某个配置文件后的Document * @throws Exception xml文件不存在 */ public static Document parse( String xmlFile ) throws Exception { // 绑定XML文件,建造DOM树 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document domTree = db.parse( xmlFile ); return domTree; } /** * 获得某节点下的某个子节点(指定子节点名称,和某个属性的值) * 即获取parentElement下名字叫childName,并且属性attributeName的值为attributeValue的子结点 * @param parentElement 要获取子节点的那个父节点 * @param childName 要获取的子节点名称 * @param attributeName 要指定的属性名称 * @param attributeValue 要指定的属性的值 * @return 符合条件的子节点 * @throws Exception 子结点不存在或有多个符合条件的子节点 * @author HX_2008-12-01 */ public static Element getChildElement( Element parentElement, String childName, String attributeName, String attributeValue ) throws Exception { NodeList list = parentElement.getElementsByTagName( childName ); int count = 0; Element curElement = null; for ( int i = 0 ; i < list.getLength() ; i ++ ) { Element child = ( Element )list.item( i ); String value = child.getAttribute( attributeName ); if ( true == value.equals( attributeValue ) ) { curElement =

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值