本文主要讲解java中XML解析方式 dom4j

dom4j是sourceforge.net上的一个开源项目,主要用于对XML的解析。从2001年7月发布第一版以来,已陆续推出多个版本,目前最高版本为1.6。

dom4j专门针对Java开发,使用起来非常简单、直观,在Java界,dom4j正迅速普及。

应用时需要引入的jar包 dom4j-1.6.1.jar

另外jaxen-1.1-beta-6.jar包也推荐引入,否则执行时可能抛java.lang.NoClassDefFoundError: org/jaxen/JaxenException异常。


DOM4J获取Document对象的方式:

//第一种  通过sax解析器将读取到文档内容构建为Document对象

SAXReader saxReader = new SAXReader();

Document doc = saxReader.read(本类名.class.getResourceAsStreanm("/person.xml"));


//第二种 通过XML文本数据构建Document对象

String text = "<student id=\"1001\"><name>张三</name><age>20</age><<\student>";

Document doc = DocumentHelper.parseText(text);


//第三种 通过DocumentHelper创建Document对象

Document doc = DocumentHelper.createDocument();

Element root = doc.addElement("student");


//第四种 通过DocumentFactory创建Document对象

DocumentFactory factory = DocumentFactory.getInstance();

Document doc = factory.createDocument();


本文主要讲解对指定xml文件的解析,采用第一种方式。

其中read是一个重载方法,可以传InputStream、File、Url、String、Reader、InputSource等各种源

封装类:其中UtilsDom4j为本工具类的类名

	// 获取文件
	public static Document parse(String name) {
		SAXReader reader = new SAXReader();
		Document document = null;
		try {
			document = reader.read(UtilsDom4j.class.getResourceAsStream(name));
		} catch (DocumentException e) {
			e.printStackTrace();
		}
		return document;
	}

取得Root节点:

	public Element getRootElement(Document document){
		return document.getRootElement();
	}

遍历节点:

(遍历节点的方法很多,常用的有枚举、递归。本文采用递归方法)

为了更直观的查看遍历结果,对节点的父节点、属性、文本、子节点增加了打印输出语句。

	// 递归遍历节点、属性、值、文本
	@SuppressWarnings("unchecked")
	public static void listNodes(Element node) {
		if (node.getParent()!=null) {
			System.out.print("节点"+node.getParent().getName()+"\t的子");
		}
		System.out.print("节点" + node.getName() + ":");
		// 当前节点的所有属性
		List<Attribute> list = node.attributes();
		for (Attribute attr : list) {
			System.out.print("\t属性" + attr.getName() + "=" + attr.getValue()+ "\t");
		}
		// 当前节点的文本
		if (!(node.getTextTrim().equals(""))) {
			System.out.println("\t文本" + node.getText());
		} else {
			System.out.println();
		}

		// 递归遍历子节点
		for (Iterator<Element> i = node.elementIterator(); i.hasNext();) {
			Element e = i.next();
			listNodes(e);
		}
	}

遍历节点后,可以按照各自的需求对文档进行操作:

例如:查找 根节点contacts下的id=2的contact的节点下addresses下address下street的地址文本,后进行修改

		List<Element> list = root.elements();
		for (Element e : list) {
			Attribute attribute = e.attribute("id");
			if ("2".equals(attribute.getValue())) {
				Element street=e.element("addresses").element("address").element("street");
				System.out.println(street.getText());
				street.setText("关山大道20号3单元");
				System.out.println(street.getText());
			}
		}

也可以导入引文提到的jar包 jaxen-1.1-beta-6.jar来进行多重查找:

		@SuppressWarnings("unchecked")
		List<Node> nodes = root.selectNodes("contact[@id='2']/addresses/address/street");
		for (Node n : nodes) {
			System.out.println(n.getName()+"的文本修改前是:"+n.getText());
			n.setText("关山大道20号3单元");
			System.out.println(n.getName()+"的文本修改后是:"+n.getText());
		}


由于上述2个代码块不具备通用性,故没有写入封装类。


最后内容输出。

	//把document对象写入文件(新文件或覆盖原文件)
	public static void writer(Document document,String fileName){
		//createCompactFormat()紧凑格式
		//createPrettyPrint()缩进格式
		OutputFormat format = OutputFormat.createPrettyPrint();
		format.setEncoding("UTF-8");
		XMLWriter writer=null;
		try {
			//创建新文件
			File parent = new File(fileName).getParentFile();
			if (!parent.exists()) {
				parent.mkdirs();
			}
			
			writer = new XMLWriter(new FileWriter(fileName), format);
			writer.write(document);
			writer.flush();
			writer.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}



Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐