使用xpath获取xml指定节点或节点集工具类

使用xpath获取xml指定节点的属性

 

 

1. XmlXPathUtil.java

 

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.util.Iterator;
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.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

/**
 * 
 * 
 * <DL>
 * <DT><B> 使用路径表达式(XPath)来获取XML文档中的节点或节点集工具类 </B></DT>
 * <p>
 * <DD>详细介绍</DD>
 * </DL>
 * <p>
 * 
 * <DL>
 * <DT><B>使用范例</B></DT>
 * <p>
 * <DD>使用范例说明</DD>
 * </DL>
 * <p>
 * 
 * @author 周典
 * @version
 */

public class XmlXPathUtil {

	private static final Log logger = LogFactory.getLog(XmlXPathUtil.class);

	/** XML编码 */
	private String encoding = "utf-8";

	private NamespaceContext defaultNamespaceContext;

	public XmlXPathUtil() {
		defaultNamespaceContext = new NamespaceContext() {
			private Map<String, String> m_prefixMap = null;

			public String getNamespaceURI(String prefix) {
				if (null == prefix) {
					throw new NullPointerException("Null prefix");
				} else {
					if ("xml".equals(prefix)) {
						return XMLConstants.XML_NS_URI;
					}
					if (null != m_prefixMap) {
						for (String key : m_prefixMap.keySet()) {
							if (key.equals(prefix)) {
								return m_prefixMap.get(key);
							}
						}
					}
				}
				return XMLConstants.NULL_NS_URI;
			}

			public String getPrefix(String uri) {
				throw new UnsupportedOperationException();
			}

			public Iterator getPrefixes(String uri) {
				throw new UnsupportedOperationException();
			}
		};
	}

	/**
	 * 
	 * 获取XPath的值
	 * 
	 * @param query
	 * 
	 * @param xmlDocument
	 * 
	 * @param defaultNamespaceContext
	 * 
	 * @return String
	 */
	public String evaluateXPath(String query, Node xmlDocument,
			NamespaceContext defaultNamespaceContext) {
		String result = null;
		XPathFactory factory = XPathFactory.newInstance();
		XPath xpath = factory.newXPath();
		if (defaultNamespaceContext == null) {
			defaultNamespaceContext = this.defaultNamespaceContext;
		}
		xpath.setNamespaceContext(defaultNamespaceContext);
		XPathExpression expr = null;
		try {
			expr = xpath.compile(query);
		} catch (XPathExpressionException xpee) {
			Throwable x = xpee;
			if (null != xpee.getCause()) {
				x = xpee.getCause();
				if ("javax.xml.transform.TransformerException".equals(x
						.getClass().getName())) {
					if (logger.isDebugEnabled()) {
						logger.debug("xpath表达式错误:所有的命名空间需要转换。");
					}
				} else {
					if (logger.isDebugEnabled()) {
						logger.debug("xpath表达式错误:可能表达式格式有误。");
					}
				}
			}
			return null;
		}
		try {
			result = (String) expr.evaluate(xmlDocument, XPathConstants.STRING);
		} catch (XPathExpressionException e) {
			e.printStackTrace();
		}
		return result;
	}

	/**
	 * 加载XML String资源
	 * 
	 * @param xmlString
	 *            xml格式的字符串
	 * @return Node
	 * 
	 */
	public Node loadXMLResource(String xmlString) {
		if (0xFEFF == xmlString.charAt(0)) {
			xmlString = xmlString.substring(1);
		}
		InputSource source = new InputSource(new BufferedReader(
				new StringReader(xmlString)));
		return this.xmlSourceToDocument(source);
	}

	/**
	 * 加载XML byte[]资源
	 * 
	 * @param xmlFile
	 *            xml文件
	 * @return Node
	 * 
	 */
	public Node loadXMLResource(byte xmlByte[]) {
		String xmlString = "";
		try {
			xmlString = new String(xmlByte, encoding);
		} catch (UnsupportedEncodingException e) {
			if (logger.isDebugEnabled()) {
				logger.debug(e.getMessage());
			}
		}
		if (0xFEFF == xmlString.charAt(0)) {
			xmlString = xmlString.substring(1);
		}
		InputSource source = new InputSource(new BufferedReader(
				new StringReader(xmlString)));
		return this.xmlSourceToDocument(source);
	}

	/**
	 * 加载XML File资源
	 * 
	 * @param xmlFile
	 *            xml文件
	 * @return Node
	 * 
	 */
	public Node loadXMLResource(File xmlFile) {
		InputSource source = null;
		try {
			source = new InputSource(new FileInputStream(xmlFile));
		} catch (FileNotFoundException e) {
			if (logger.isDebugEnabled()) {
				logger.debug(e.getMessage());
			}
		}
		return this.xmlSourceToDocument(source);
	}

	/**
	 * 
	 * 把xml source 转换为Document
	 * 
	 * @param source
	 * 
	 * @return
	 * 
	 */
	private Node xmlSourceToDocument(InputSource source) {
		source.setEncoding(encoding);
		Document document = null;
		try {
			document = loadDocument(source);
		} catch (SAXParseException spe) {
			if (null != spe.getSystemId()) {
				if (logger.isDebugEnabled()) {
					logger.debug("xpath解析错误,出错的行数是:" + spe.getLineNumber()
							+ ",uri:" + spe.getSystemId());
					logger.debug(spe.getMessage());
				}
			} else {
				if (logger.isDebugEnabled()) {
					logger.debug(spe.getMessage());
				}
			}
			Exception x = spe;
			if (null != spe.getException()) {
				x = spe.getException();
			}
		} catch (SAXException se) {
			document = null;
			if (logger.isDebugEnabled()) {
				logger.debug("解析XML错误,请确保存在格式正确的XML文档。");
			}
			Exception x = se;
			if (null != se.getException()) {
				x = se.getException();
			}
		} catch (IOException ioe) {
			document = null;
			if (logger.isDebugEnabled()) {
				logger.debug("不能加载文档,文档不可读取。");
			}
		}
		return document;
	}

	/**
	 * 
	 * 从InputSource加载document
	 * 
	 * @param source
	 * @return Node
	 * @throws SAXException
	 * @throws IOException
	 */
	private Document loadDocument(InputSource source) throws SAXException,
			IOException {
		Document document = null;
		DocumentBuilder parser = null;
		DocumentBuilderFactory domFactory = DocumentBuilderFactory
				.newInstance();
		domFactory.setNamespaceAware(true);
		domFactory.setValidating(false);
		try {
			parser = domFactory.newDocumentBuilder();
		} catch (ParserConfigurationException pce) {
			if (logger.isDebugEnabled()) {
				logger.debug(pce.getMessage());
			}
		}
		parser.reset();
		document = parser.parse(source);
		return document;
	}

	/**
	 * 
	 * 设置xml编码
	 * 
	 * @param encoding
	 */
	public void setEncoding(String encoding) {
		this.encoding = encoding;
	}

	/**
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		String xmlString = "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
		xmlString += "<books>";
		xmlString += "<book><name>Action1</name></book>";
		xmlString += "<book><name first='asdf'>Action2</name></book>";
		xmlString += "</books>";
		XmlXPathUtil xmlXPathUtil = new XmlXPathUtil();
		xmlXPathUtil.setEncoding("utf-8");
		Node fileNode = xmlXPathUtil
				.loadXMLResource(new File(
						"F:\\客户信息查询.xml"));
		Node strNode = xmlXPathUtil.loadXMLResource(xmlString);
		String strValue = xmlXPathUtil.evaluateXPath("//book", strNode, null);
		String fileValue = xmlXPathUtil
				.evaluateXPath(
						"/service[ @name='' ]/sys-header/data[ @name='SYS_HEAD' ]/struct/data[ @name='MESSAGE_TYPE' ]/field[1]/text()",
						fileNode, null);
		System.out.println("execute result: " + strValue);
		System.out.println("execute result: " + fileValue);
	}
}


2. 客户信息查询.xml

 

<?xml version="1.0" encoding="GB2312"?>
<service name="">
	<sys-header>
		<data name="SYS_HEAD">
			<struct>
				<data name="MESSAGE_TYPE">
					<field type="string" length="4" encrypt-mode="">1400</field>
					<field type="string" length="4" encrypt-mode="">1401</field>
				</data>
				<data name="MESSAGE_CODE">
					<field type="string" length="6" encrypt-mode="">9100</field>
				</data>
				<data name="SERVICE_CODE">
					<field type="string" length="8" encrypt-mode="">SVR_INQUIRY1</field>
					<field type="string" length="8" encrypt-mode="">SVR_INQUIRY2</field>
				</data>
			</struct>
		</data>
	</sys-header>
	<app-header>
		<data name="APP_HEAD">
			<struct>
				<data name="PGUP_OR_PGDN">
					<field type="string" length="1" encrypt-mode="">1</field>
				</data>
				<data name="TOTAL_NUM">
					<field type="string" length="10" encrypt-mode="">10</field>
				</data>
				<data name="CURRENT_NUM">
					<field type="string" length="10" encrypt-mode="">0</field>
				</data>
				<data name="PAGE_START">
					<field type="string" length="10" encrypt-mode="">0</field>
				</data>
				<data name="PAGE_END">
					<field type="string" length="10" encrypt-mode="">0</field>
				</data>
			</struct>
		</data>
	</app-header>
	<body>
		<data name="CLIENT_NO">
			<field type="string" length="12" encrypt-mode="">1234567890123</field>
		</data>
		<data name="GLOBAL_ID">
			<field type="string" length="25" encrypt-mode="">1234567890123456789012345</field>
		</data>
		<data name="GLOBAL_TYPE">
			<field type="string" length="3" encrypt-mode="">123</field>
		</data>
		<data name="ISS_COUNTRY">
			<field type="string" length="3" encrypt-mode="">123</field>
		</data>
	</body>
</service>

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值