`
chris_freedream
  • 浏览: 32927 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
最近访客 更多访客>>
社区版块
存档分类
最新评论

XPath parser in Java

阅读更多
  • 1.概览
  • 2.解决要点
  • 3.代码实现
  • 4.测试代码实现
  • 5.测试结果
  • 6.总结


1.概览

本主题旨在不依赖第三方软件情况下如何使用Java实现XPath的解析。

2.解决要点

1)如何把XML文件/XML字符流转换为DOM模型下的Node/Element.
 
2)XML文件/XML字符流编码格式的指定。

3)提供XML的Namespace Resolver.

4)调用XPath的相关API并依赖用户指定的experssion进行解析,并返回结果。

3.代码实现

package com.chris.xpath;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintStream;
import java.io.StringReader;

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.w3c.dom.Node;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
/**
 * <code>XPathUtil</code>.
 * @author chris.wang
 */
public class XPathUtil
{
	private PrintStream error = System.err;

	/**
	 * Populate XPath-expression.
	 * @param query
	 * @param xmlDocument
	 * @param defaultNamespaceContext
	 * @return value of element or attribute.
	 */
	public String evaluateXPath( String query, Node xmlDocument,
											NamespaceContext defaultNamespaceContext )
	{
		String result = null;

		XPathFactory factory = XPathFactory.newInstance();

		XPath xpath = factory.newXPath();

		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()) )
				{
					error
							.println("Error compiling xpath expression ["
									+ query
									+ "].  Could all the required namespaces be resolved from the previous response?");
				}
				else
				{
					error.println("Error compiling xpath expression [" + query
							+ "].  Is the expression well-formed in XML Spy?");
				}
			}

			x.printStackTrace(error);

			return null;
		}

		try
		{
			result = (String) expr.evaluate(xmlDocument, XPathConstants.STRING);
		}
		catch ( XPathExpressionException e )
		{
			e.printStackTrace(error);
		}

		return result;
	}

	/**
	 * Convert xmlString into Node.
	 * @param xmlString
	 * @param encodingHint encoding type.
	 * @return Node
	 */
	public Node loadXMLResource( String xmlString, String encodingHint )
	{
		Node document = null;

		if ( 0xFEFF == xmlString.charAt(0) )
		{
			xmlString = xmlString.substring(1);
		}

		InputSource source = new InputSource(new BufferedReader(new StringReader(
				xmlString)));

		if ( null != encodingHint )
		{
			source.setEncoding(encodingHint);
		}

		// parse the XML purely as well-formed XML and get a DOM tree
		// represenation.
		try
		{
			document = loadDocument(source);
		}
		catch ( SAXParseException spe )
		{
			// Error generated by the parser
			if ( null != spe.getSystemId() )
			{
				error.println("\n** XML Parsing error **, line "
						+ spe.getLineNumber() + " character " + spe.getColumnNumber()
						+ ", uri=" + spe.getSystemId());
				error.println("   " + spe.getMessage() + "\n"); // NOPMD
			}
			else
			{
				error.println("\n** XML Parsing error ** : " + spe.getMessage()
						+ "\n");
			}

			// Use the contained exception, if any
			Exception x = spe;

			if ( null != spe.getException() )
			{
				x = spe.getException();
			}

			x.printStackTrace(error);
		}
		catch ( SAXException se )
		{
			document = null;

			error
					.println("Error parsing the XML resource - is the XML valid and well-formed?");

			// Use the contained exception, if any
			Exception x = se;

			if ( null != se.getException() )
			{
				x = se.getException();
			}

			x.printStackTrace(error);
		}
		catch ( IOException ioe )
		{
			document = null;

			error
					.println("Error loading the XML resource - can the xmlString be read?");

			ioe.printStackTrace(error);
		}

		return document;
	}

	/**
	 * Load document from InputSource( i.e. XML file or other stream ).
	 * @param source
	 * @return Node of DOM.
	 * @throws SAXException
	 * @throws IOException
	 */
	public Node loadDocument( InputSource source ) throws SAXException,
			IOException
	{
		Node document = null;

		// Get a parser capable of parsing XML into a DOM tree
		DocumentBuilder parser = null;

		// Create the dom factory
		DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();

		domFactory.setNamespaceAware(true);
		domFactory.setValidating(false); // only for DocType (dtd) validation

		try
		{
			parser = domFactory.newDocumentBuilder();
		}
		catch ( ParserConfigurationException pce )
		{
			pce.printStackTrace(error);
		}

		// parse the XML purely as well-formed XML and get a DOM tree
		// represenation.
		parser.reset();

		document = parser.parse(source);

		return document;
	}

}


4.测试代码的实现

package com.chris.xpath;

import java.util.Iterator;
import java.util.Map;

import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;

import org.w3c.dom.Node;

public class XPathUtilDriver
{

	private static NamespaceContext defaultNamespaceContext;
	static
	{
		defaultNamespaceContext = new NamespaceContext()
		{

			private Map<String, String> m_prefixMap = null; // NOPMD

			public String getNamespaceURI( String prefix )
			{
				if ( null == prefix )
				{
					throw new NullPointerException("Null prefix"); // NOPMD
				}
				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;
			}

			// This method isn't necessary for XPath processing.
			public String getPrefix( String uri )
			{
				throw new UnsupportedOperationException();
			}

			// This method isn't necessary for XPath processing either.
			public Iterator getPrefixes( String uri )
			{
				throw new UnsupportedOperationException();
			}

		};
	}

	public static void main( String[] args )
	{
		String xmlString = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
				+ "<books><book><name>JUnit in Action</name>" + "</book>"
				+ "</books>";
		XPathUtil util = new XPathUtil();
		Node node = util.loadXMLResource(xmlString, "utf-8");
		String value = util.evaluateXPath("//books/book[1]/name/text()", node,
														defaultNamespaceContext);
		System.out.println("execute result" + value);
	}
}


5.测试结果

execute result:JUnit in Action


6.总结

1)如果要是namespace产生效果一定要加上domFactory.setNamespaceAware(true), 不然解析后的Node可能不能用.
2)XML可能涉及到不同的编码,所以编码问题也是一个注意点。
3)第三方开发软件如JDOM,DOM4j对XPath都有很好的支持,个人觉得使用也是很方便,如果你的项目中刚好用的这个组件,那一些解析的操作就可以省了。
分享到:
评论

相关推荐

    vue3.2+ts+vite+admin 开发的admin管理系统模板

    vue3.2+ts+vite+admin 开发的admin管理系统模板

    chromedriver-win64-124版本浏览器驱动

    自动化测试工具selenium使用的浏览器驱动下载 chromedriver驱动压缩包 Java web 自动化测试工具需要使用的chromedriver浏览器驱动

    node-v8.1.0-darwin-x64.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    2. Power Query 逆透视&分组依据.xlsx

    2. Power Query 逆透视&分组依据.xlsx

    Java 实现微信红包分配算法内含源码以及说明书可以自己运行复现.zip

    Java 实现微信红包分配算法内含源码以及说明书可以自己运行复现.zip

    node-v9.11.1-darwin-x64.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    node-v9.3.0-linux-ppc64le.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    2024-2030中国WiFi连接洗衣机市场现状研究分析与发展前景预测报告.docx

    2024-2030中国WiFi连接洗衣机市场现状研究分析与发展前景预测报告

    node-v8.2.0-linux-ppc64le.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    基于QT+C++实现的多列时间轴控件+源码+文档

    用法链接:https://menghui666.blog.csdn.net/article/details/138544216?spm=1001.2014.3001.5502 Qt 多列时间轴控件。 可与多段字符串格式自由转换,也可手动添加列表项。 专门用来以时间轴作为事件线发展顺序的故事大纲。 特点 时间背包功能:记录所有物品或属性发生的变化,随时回溯 时间可输入任意内容,不限于时间 每一时间段允许多列,即多个文字节点 全自动调整节点大小(宽高),尽量看起来舒服 行与行、列与列 之间任意拖拽更换顺序 可与文字自由转换,默认一段为一个文字节点 方便的多行操作 按需修改快捷键 所有编辑可撤销 美观的调整动画

    基于SSM个人记账本理财管理系统源码+文档说明+数据库(高分项目).zip

    基于SSM个人记账本理财管理系统源码+文档说明+数据库(高分项目).zip 本资源中的源码都是经过本地编译过可运行的,评审分达到95分以上。资源项目的难度比较适中,内容都是经过助教老师审定过的能够满足学习、使用需求,如果有需要的话可以放心下载使用。 基于SSM个人记账本理财管理系统源码+文档说明+数据库(高分项目).zip 本资源中的源码都是经过本地编译过可运行的,评审分达到95分以上。资源项目的难度比较适中,内容都是经过助教老师审定过的能够满足学习、使用需求,如果有需要的话可以放心下载使用。 基于SSM个人记账本理财管理系统源码+文档说明+数据库(高分项目).zip 本资源中的源码都是经过本地编译过可运行的,评审分达到95分以上。资源项目的难度比较适中,内容都是经过助教老师审定过的能够满足学习、使用需求,如果有需要的话可以放心下载使用。 基于SSM个人记账本理财管理系统源码+文档说明+数据库(高分项目).zip 本资源中的源码都是经过本地编译过可运行的,评审分达到95分以上。资源项目的难度比较适中,内容都是经过助教老师审定过的能够满足学习、使用需求,如果有需要的话可以放心下载使用。

    代替AWCC驱动的TCC软件

    代替AWCC驱动的TCC软件

    app.apk

    app.apk

    C++11&14 高速上手教程内含源码以及说明书可以自己运行复现.zip

    C++11&14 高速上手教程内含源码以及说明书可以自己运行复现.zip

    node-v8.11.4-linux-ppc64le.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    国际象棋游戏数据集 CSV 2W+场次 (Lichess)

    这是一组从网站上的精选用户那里收集的 20,000 多款游戏 Lichess.org,以及如何收集更多游戏。我还将在未来收集更多游戏时上传它们。此套装包含:游戏 ID;额定值 (T/F);开始时间;结束时间;匝数;游戏状态;胜利者;时间增量;白色玩家 ID;白人球员评分;黑色玩家 ID;黑人球员评分;所有动作均采用标准国际象棋符号;Opening Eco(任何给定开口的标准化代码,在此处列出); 开场名称;开盘(开盘阶段的移动次数)

    大语言模型高清PDF-人民大学

    大语言模型高清PDF--人民大学。2022 年底,ChatGPT 震撼上线,大语言模型技术迅速“席卷”了整个社会,人工智能技术因此迎来了一次重要进展。面对大语言模型的强大性能,我们不禁要问:支撑这些模型的背后技术究竟是什么?这一问题无疑成为了众多科研人员的思考焦点。 不同综述,本次中文版书籍更注重为大模型技术的入门读者提供讲解,为此我们在内容上进行了大幅度的更新与重组,力图展现一个整体的大模型技术框架和路线图。本书适用于具有深度学习基础的高年级本科生以及低年级研究生使用,可以作为一本入门级的技术书籍

    node-v9.11.2-linux-armv7l.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    2024年中国齿槽扭矩测试仪行业研究报告.docx

    2024年中国齿槽扭矩测试仪行业研究报告

    node-v10.0.0-linux-armv7l.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

Global site tag (gtag.js) - Google Analytics