分享一个 org.w3c.dom XML 封装

简介: 之前解析 XML 大多在网页中完成。如果切换到 Java 中可能是 Dom4j 或者其他。不过对于一些小 Case,JDK 自带的 Dom 就可以了,而且可以省掉第三方 JAR,何乐不为呢?于是我参照了一位大侠写的,稍微重构一下,分享给大家。

之前解析 XML 大多在网页中完成。如果切换到 Java 中可能是 Dom4j 或者其他。不过对于一些小 Case,JDK 自带的 Dom 就可以了,而且可以省掉第三方 JAR,何乐不为呢?于是我参照了一位大侠写的,稍微重构一下,分享给大家。

测试用例:http://git.oschina.net/sp42/ajaxjs/blob/master/java/src/test/com/ajaxjs/test/util/TestXML.java

import static org.junit.Assert.*;

import java.util.List;

import org.junit.Before;
import org.junit.Test;

import com.ajaxjs.util.XML_Wrapper;

public class TestXML {
	XML_Wrapper root;
	String saveTo;
	
	@Before
	public void setUp() {
		root = XML_Wrapper.getRoot("d:/temp/test.xml");
		saveTo = "d:/temp/test2.xml";
	}

	@Test
	public void 解析xml() {
		List<XML_Wrapper> pList = root.getChildrenElement("property");

		for (XML_Wrapper d : pList) {
			System.out.println(
					d.child("name").text() + ", " + d.child("value").text() + ", " + d.child("description").text());
			assertNotNull(d);
		}
	}

	@Test
	public void 修改xml() {
		List<XML_Wrapper> pList = root.getChildrenElement("property");

		XML_Wrapper d = pList.get(0);
		XML_Wrapper nameDom = d.child("name");
		nameDom.setAttribute("a", "2");
		nameDom.setAttribute("b", "3");
		nameDom.text("测试呵呵");

		assertNotNull(nameDom);
		d.child("description").text("添加描述……");

		root.write(saveTo);
	}

	@Test
	public void 新建xml() {
		XML_Wrapper root = XML_Wrapper.newDom("configuration");

		XML_Wrapper propertyDom = root.addElement("property");
		propertyDom.addElement("name", "名称");
		propertyDom.addElement("value", "值");
		XML_Wrapper dDom = propertyDom.addElement("description", "描述");
		dDom.setAttribute("a", "2");

		root.write(saveTo);
	}
}

测试 XML

<?xml version="1.0"?>
<configuration>
	<property>
	  <name a="1">host</name>
	  <value>http://192.168.3.249</value>
	  <description>系统主机地址</description>
	</property>

	<property>
	  <name>login</name>
	  <value>/page/Default.jsp</value>
	  <description>登陆页面</description>
	</property>
</configuration>

完整源码 http://git.oschina.net/sp42/ajaxjs/blob/master/java/src/main/com/ajaxjs/util/XML_Wrapper.java

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import com.ajaxjs.Constant;

/**
 * DOM 操控 XML
 */
public class XML_Wrapper {
	private Element element;

	/**
	 * 传入一个元素
	 * 
	 * @param element
	 *            元素
	 */
	private XML_Wrapper(Element element) {
		this.element = element;
	}

	/**
	 * 返回元素
	 * 
	 * @return 元素
	 */ 
	public Element getDomElement() {
		return element;
	}

	/**
	 * 设置属性
	 * 
	 * @param name
	 * @param value
	 */
	public void setAttribute(String name, String value) {
		element.setAttribute(name, value);
	}

	/**
	 * 设置节点文本值
	 * 
	 * @param value
	 *            节点文本值
	 */
	public void text(String value) {
		Node textNode = element.getFirstChild();
		textNode.setNodeValue(value);
	}

	/**
	 * 获取节点文本值
	 * 
	 * @return 节点文本值
	 */
	public String text() {
		Node textNode = element.getFirstChild();
		return textNode.getNodeValue();
	}

	/**
	 * 添加子节点
	 * 
	 * @param name
	 *            子节点 tag
	 * @return 子节点 XML_Wrapper
	 */
	public XML_Wrapper addElement(String name) {
		Element element = this.element.getOwnerDocument().createElement(name.trim());
		this.element.appendChild(element);

		return new XML_Wrapper(element);
	}

	/**
	 * 添加子节点,并设置文本
	 * 
	 * @param name
	 *            子节点 tag
	 * @param value
	 *            文本
	 * @return 子节点 XML_Wrapper
	 */
	public XML_Wrapper addElement(String name, String value) {
		XML_Wrapper child = addElement(name);
		child.getDomElement().appendChild(element.getOwnerDocument().createTextNode(value));

		return child;
	}

	/**
	 * 返回子节点列表
	 * 
	 * @param name
	 *            子节点 tag
	 * @return
	 */
	public NodeList getChildren(String name) {
		NodeList nodeList = element.getElementsByTagName(name);
		if ((nodeList == null) || (nodeList.getLength() < 1)) {
			return null;
		}
		return nodeList;
	}

	/**
	 * 是否某个子节点
	 * 
	 * @param name
	 *            子节点 tag
	 * @return
	 */
	public boolean hasChild(String name) {
		return getChildren(name) != null;
	}

	/**
	 * 返回第一个子节点
	 * 
	 * @param name
	 *            子节点 tag
	 * @return
	 */
	public XML_Wrapper child(String name) {
		return getFirstChild(name);
	}

	/**
	 * 返回第一个子节点
	 * 
	 * @param name
	 *            子节点 tag
	 * @return
	 */
	public XML_Wrapper getFirstChild(String name) {
		if (hasChild(name)) {
			Node node = getChildren(name).item(0);
			return new XML_Wrapper((Element) node);
		}
		return null;
	}

	/**
	 * 获取子节点,忽略文本节点
	 * 
	 * @param name
	 *            子节点 tag
	 * @return
	 */
	public List<XML_Wrapper> getChildrenElement(String name) {
		NodeList nodeList = getChildren(name);
		if (nodeList == null)
			return null;

		List<XML_Wrapper> list = new ArrayList<>();

		for (int i = 0; i < nodeList.getLength(); i++) {
			Node node = nodeList.item(i);
			if (node.getNodeType() == Node.ELEMENT_NODE) {
				Element e = (Element) node;
				list.add(new XML_Wrapper(e));
			}
		}

		return list;
	}

	/**
	 * 打印子节点
	 */
	public void printChild() {
		NodeList nodeList = element.getChildNodes();
		for (int i = 0; i < nodeList.getLength(); i++) {
			Node node = nodeList.item(i);
			System.out.println(
					"节点名: " + node.getNodeName() + ", 节点值: " + node.getNodeValue() + ", 节点类型: " + node.getNodeType());
		}
	}

	/**
	 * 移除子节点
	 * 
	 * @param name
	 *            子节点 tag
	 */
	public void removeChild(String name) {
		NodeList nodeList = getChildren(name);
		if (nodeList == null) {
			return;
		}
		for (int i = 0; i < nodeList.getLength(); i++) {
			element.removeChild(nodeList.item(i));
		}
	}

	public void write(OutputStream os) {
		write(os, Constant.encoding_UTF8);
	}

	/**
	 * 
	 * @param os
	 * @param encoding
	 */
	public void write(OutputStream os, String encoding) {
		TransformerFactory tFactory = TransformerFactory.newInstance();
		tFactory.setAttribute("indent-number", 2);

		try {
			Transformer transformer = tFactory.newTransformer();
			transformer.setOutputProperty(OutputKeys.ENCODING, encoding);
			transformer.setOutputProperty(OutputKeys.INDENT, "yes");
			transformer.setOutputProperty(OutputKeys.STANDALONE, "yes");
			transformer.transform(new DOMSource(element.getOwnerDocument()), new StreamResult(new OutputStreamWriter(os)));
		} catch (TransformerFactoryConfigurationError | TransformerException e) {
			e.printStackTrace();
		}
	}

	public void write(String xmlFile) {
		write(xmlFile, Constant.encoding_UTF8);
	}

	public void write(String xmlFile, String encoding) {
		try (OutputStream os = new FileOutputStream(xmlFile);) {
			write(os, encoding);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 创建一份新的 XML,包含一个新的节点(根节点)
	 * 
	 * @param rootName
	 *            根节点名称
	 * @return
	 */
	public static XML_Wrapper newDom(String rootName) {
		Document doc = getDocBuilder().newDocument();
		doc.setXmlStandalone(true);

		// getDocBuilder();
		Element root = doc.createElement(rootName);
		doc.appendChild(root);

		return new XML_Wrapper(root);
	}

	private static DocumentBuilder getDocBuilder() {
		try {
			return DocumentBuilderFactory.newInstance().newDocumentBuilder();
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 送入流创建 XML 文档
	 * 
	 * @param is
	 *            流,并不会自动关闭的
	 * @return
	 */
	public static Element getRoot(InputStream is) {
		Document doc = null;

		try {
			doc = getDocBuilder().parse(is);
			return doc.getDocumentElement();
		} catch (SAXException | IOException e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 
	 * @param xmlFile
	 * @return
	 */
	public static XML_Wrapper getRoot(String xmlFile) {
		try (InputStream is = new FileInputStream(xmlFile);) {
			return new XML_Wrapper(getRoot(is));
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * XPath
	 * 
	 * @param xmlFile
	 *            XML 文件路径
	 * @param encoding
	 *            XML 文件编码
	 * @param expression
	 *            XPath 表达式
	 * @param namespaceMap
	 *            命名空间
	 * @return
	 */
	public static String xpath(String xmlFile, String encoding, String expression, final Map<String, String> namespaceMap) {
		XPath xpath = XPathFactory.newInstance().newXPath();
		
		if (namespaceMap != null) {
			xpath.setNamespaceContext(new NamespaceContext() {
				@Override
				public String getNamespaceURI(String prefix) {
					if (prefix == null)
						throw new NullPointerException("Null prefix");
					else if ("xml".equals(prefix))
						return XMLConstants.XML_NS_URI;
					else if (namespaceMap.containsKey(prefix))
						return namespaceMap.get(prefix);
					
					return XMLConstants.NULL_NS_URI;
				}
				
				@Override
				public String getPrefix(String namespaceURI) {
					throw new UnsupportedOperationException();
				}
				
				@Override
				public Iterator<?> getPrefixes(String namespaceURI) {
					throw new UnsupportedOperationException();
				}
			});
		}
		
		String value = null;
		
		try (
			FileInputStream is = new FileInputStream(xmlFile);
			InputStreamReader isr = new InputStreamReader(is, encoding);
		) {
			InputSource source = new InputSource(isr);
			
			try {
				value = xpath.evaluate(expression, source);
			} catch (XPathExpressionException e) {
				e.printStackTrace();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}

		return value;
	}
}
目录
相关文章
|
3天前
|
XML Web App开发 JavaScript
XML DOM 解析器
**XML DOM解析器将XML转换为JavaScript对象,允许在浏览器中操作XML。浏览器通常内置XML解析器,如XMLHttpRequest用于加载XML文档。以下代码示例展示如何加载&quot;books.xml&quot;:** ```markdown - 创建XMLHttpRequest对象(或使用ActiveXObject for IE6/IE5) - 打开GET请求到&quot;books.xml&quot; - 发送请求 - xmlDoc变量存储响应的XML DOM ``` 此过程使开发者能够通过JavaScript遍历、修改XML文档的结构。
|
9天前
|
XML Java 数据格式
必知的技术知识:java基础73dom4j修改xml里面的内容(网页知识)
必知的技术知识:java基础73dom4j修改xml里面的内容(网页知识)
11 1
|
8天前
|
XML Web App开发 JavaScript
XML DOM 解析器
**XML DOM解析器**是浏览器内置的工具,用于将XML转换为JavaScript对象,便于操作。通过XMLHttpRequest或ActiveXObject加载XML文档,如`books.xml`,创建HTTP请求并获取响应后,将XML转换为`responseXML`,形成DOM树,允许开发者遍历、修改节点。
|
12天前
|
XML JavaScript 数据格式
XML DOM 遍历节点树
该文讲述了如何遍历XML文档的节点树。通过示例代码展示如何循环访问XML元素,提取每个节点的名称和值。实例中,XML数据包含书籍信息,程序加载XML后,遍历根节点的所有子节点,依次显示它们的名称和内容。
|
12天前
|
XML 存储 JavaScript
XML DOM - 访问节点
`getElementsByTagName()` 方法用于访问 XML 文档中的节点。节点可通过节点列表(Node List)获取,它类似数组。代码示例加载 &quot;books.xml&quot; 到 xmlDoc,然后将所有书签存储在变量 x 中。可以遍历节点树、使用关系导航或 getElementsByTagName() 访问特定节点。
|
2天前
|
XML JavaScript 数据格式
XML DOM 浏览器差异
现代浏览器均支持W3C DOM,但存在差异,如处理XML中节点间的空白和换行。IE不将这些视为文本节点,而其他浏览器则会。示例显示,一个包含CR/LF和空格的XML文件在IE中解析有4个子节点,而在其他浏览器中有9个。`loadXMLDoc()`加载XML后,`documentElement.childNodes.length`的值因浏览器而异。
|
2天前
|
XML 存储 JavaScript
XML DOM - 访问节点
`getElementsByTagName()` 方法用于访问 XML 文档中的特定节点。该方法返回一个节点列表,相当于节点数组,可用来遍历和导航节点树。例如,加载 &quot;books.xml&quot; 到 xmlDoc 后,`x = xmlDoc.getElementsByTagName(&quot;book&quot;)` 将获取所有 `&lt;book&gt;` 节点。
|
6天前
|
XML 存储 JavaScript
XML DOM - 访问节点
`getElementsByTagName()` 方法用于获取 XML 文档中指定标签名的所有节点,返回一个节点列表,类似数组。可以循环遍历节点树或利用节点关系导航来访问每个节点。例如,加载 &quot;books.xml&quot; 到 xmlDoc 后,变量 x 存储了所有 `&lt;book&gt;` 节点的列表。
|
6天前
|
XML 存储 JavaScript
XML DOM - 访问节点
`getElementsByTagName()` 方法用于访问XML文档中的特定节点。节点可按三种方式获取:使用该方法、遍历节点树或导航节点关系。`getElementsByTagName()` 返回一个节点列表,类似数组,可用于处理多个匹配节点。例如,代码加载 &quot;books.xml&quot; 到 `xmlDoc`,再将结果保存到变量 `x`。
|
4天前
|
XML 存储 JavaScript
XML DOM - 访问节点
`getElementsByTagName()` 方法用于获取 XML 文档中指定标签名的所有节点,返回一个节点列表,可遍历处理。通过节点关系及循环,能灵活访问和导航XML文档的整个节点树。例如,`xmlDoc.getElementsByTagName(&quot;book&quot;)` 返回一个包含所有 `&lt;book&gt;` 节点的数组。

相关课程

更多