`

JAXP使用及理解

 
阅读更多

 

通过读IBM-developWorks的一篇《JAXP验证》,让我对JAXP开始了全面认识,以前工作中经常会用到JAXP相关的代码,但一直都是只知道怎么用API,照搬网上的代码,也没有搞懂JAXP的实质。通过学习,并结合阅读Spring-ICO配置文件加载的源代码,现总结JAXP的使用及理解,以便于以后自己备忘(记性不好啊),如果对你有帮助,我也非常高兴。

 

简单的说,我的理解是:JAXP只是定义了一套通过JAVA操作XML文件的统一API,主要提供SAX和DOM(jaxp遵循w3c的dom标准)两种方式,但是API结构都非常相似。值得注意的是JAXP只是定义了API框架,并不提供XML的解析。虽然我们可以直接通过默认API参数获得默认的解析器(jdk1.4默认包括一种解析器Crimson,jdk5.0默认使用的是xerces了,org.apache.xerces放到了com.sun包里),但是我们可以通过多种方式改变JAXP的解析器。如:通过虚拟机启动参数,工厂方法参数等。

 

 

SAX和DOM

	SAX和DOM这里就不详细介绍,我感觉就是SAX逐行解析XML文件,通过事件通知机制操作XML; DOM则是使用内存加载XML到内存树种,通过DOM结构访问。
	一般来说SAX效率较好,用于XML数据文件,而DOM操作简单,一般用于配置文件较多。(这只是我的理解)。
 

 

以前使用XML的时候,很少关注XML的名字空间和验证,这里通过学习和总机,先记录下。

 

一下例子使用一个简单的SPRING配置文件来做测试,因为使用SPRING3.0环境,所以测试代码中也使用了一些SPRING的工具类。

 

 

代码:

 

/**
 * JAXP TEST&DEMO
 * 
 * @author zhangpu
 * 
 */
public class JAXPTest {

	private static Logger logger = LoggerFactory.getLogger(JAXPTest.class);
	/** JAXP attribute used to configure the schema language for validation. */
	private static final String SCHEMA_LANGUAGE_ATTRIBUTE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";

	/** JAXP attribute value indicating the XSD schema language. */
	private static final String XSD_SCHEMA_LANGUAGE = "http://www.w3.org/2001/XMLSchema";

	public static void main(String[] args) {

		URL url = JAXPTest.class.getResource("/applicationcontext_test.xml");
		File file = new File(url.getFile());

		// testSAXParser(file);
		testDOMBuilder(file);
	}

	/**
	 * 测试Dom方式解析XML
	 * 
	 * @param file
	 */
	public static void testDOMBuilder(File file) {
		try {
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
			// 设置Namespace有效
			factory.setNamespaceAware(true);
			// 打开验证
			factory.setValidating(true);
			//设置验证的SCHEMA方式为XSD
			factory.setAttribute(SCHEMA_LANGUAGE_ATTRIBUTE, XSD_SCHEMA_LANGUAGE);
			DocumentBuilder documentBuilder = factory.newDocumentBuilder();
			// 解析的验证文件XSD来源
			documentBuilder.setEntityResolver(new EntityResolver() {
				@Override
				public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
					Map<String, String> schemaMappings = new HashMap<String, String>();
					try {
						Properties mappings = PropertiesLoaderUtils.loadAllProperties("META-INF/spring.schemas", null);
						CollectionUtils.mergePropertiesIntoMap(mappings, schemaMappings);
						ResourceLoader rl = new DefaultResourceLoader();
						Resource resource = rl.getResource(schemaMappings.get(systemId));
						InputSource inputSource = new InputSource(resource.getInputStream());
						inputSource.setPublicId(publicId);
						inputSource.setSystemId(systemId);
						return inputSource;
					} catch (Exception e) {
						e.printStackTrace();
					}
					return null;
				}
			});

			// 解析错误处理
			documentBuilder.setErrorHandler(new ErrorHandler() {
				@Override
				public void warning(SAXParseException exception) throws SAXException {
					logger.warn(exception.getMessage());
				}

				@Override
				public void fatalError(SAXParseException exception) throws SAXException {
					logger.error(exception.getMessage());
				}

				@Override
				public void error(SAXParseException exception) throws SAXException {
					logger.error(exception.getMessage());
				}
			});
			Document document = documentBuilder.parse(file);

			Element root = document.getDocumentElement();
			printNode(root);
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	/**
	 * 递归打印document的主要节点
	 * 
	 * @param e
	 */
	private static void printNode(Element e) {
		if (e.hasChildNodes()) {
			NodeList subList = e.getChildNodes();
			for (int i = 0; i < subList.getLength(); i++) {
				Node n = subList.item(i);
				if (n instanceof Element) {
					printNode((Element) n);
				}
			}
		} else {
			StringBuffer sb = new StringBuffer();
			sb.append("<").append(e.getNodeName());
			if (e.hasAttributes()) {
				NamedNodeMap attr = e.getAttributes();
				for (int i = 0; i < attr.getLength(); i++) {
					sb.append(" ").append(attr.item(i).getNodeName()).append("=\"").append(attr.item(i).getNodeValue()).append("\"");
				}
			}
			sb.append(">");

			String content = e.getNodeValue();
			if (StringUtils.isNotEmpty(content)) {
				sb.append(content);
			}
			sb.append("</" + e.getNodeName() + ">");
			System.out.println(sb);

		}
	}

	/**
	 * SAX解析测试
	 * 
	 * @param file
	 */
	public static void testSAXParser(File file) {

		try {
			SAXParserFactory factory = SAXParserFactory.newInstance();
			factory.setNamespaceAware(true);
			factory.setValidating(true);

			SAXParser parser = factory.newSAXParser();
			parser.parse(file, new SAXParserHandler());
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * SAP解析事件回调
	 * 
	 * @author zhangpu
	 * 
	 */
	static class SAXParserHandler extends DefaultHandler {
		/**
		 * uri: Namespace URI, localName: 没有前缀的节点名称, qName: 节点全名,包括NAMEPSACE前缀,
		 * Attributes: 属性
		 */
		@Override
		public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
			logger.info("startElement - localName:" + localName + "; qName:" + qName + "; uri:" + uri);
			for (int i = 0; i < attributes.getLength(); i++) {
				logger.info("attribute_" + i + " - " + attributes.getLocalName(i) + " : " + attributes.getValue(i));
			}
		}

		@Override
		public void endElement(String uri, String localName, String qName) throws SAXException {
			logger.info("endElement - localName:" + localName + "; qName:" + qName + "; uri:" + uri);
		}

		@Override
		public void characters(char[] ch, int start, int length) throws SAXException {
			String content = new String(ch, start, length);
			content = content.trim();
			if (content.length() > 0) {
				logger.info("characters: " + content);
			}
		}

	}

}
 

 

    代码中的DOM方式解析中,如果xml文档内容合法(前面贴出)

 

合法的XML文件

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
                     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                     http://www.springframework.org/schema/context
                     http://www.springframework.org/schema/context/spring-context-3.0.xsd
                     http://www.springframework.org/schema/aop
                     http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
                     http://www.springframework.org/schema/tx
                     http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

	<context:annotation-config />

	<context:property-placeholder location="classpath:database.properties" />

	<bean id="userManager" class="main.spring.UserManagerImpl" />

</beans>

 运行结果:

 

 

<context:annotation-config></context:annotation-config>
<context:property-placeholder ignore-resource-not-found="false" ignore-unresolvable="false" local-override="false" location="classpath:database.properties" system-properties-mode="FALLBACK"></context:property-placeholder>
<bean autowire="default" autowire-candidate="default" class="main.spring.UserManagerImpl" id="userManager" lazy-init="default"></bean>
 

如果XML文档中有非法(不符合XSD定义的)的内容

不合法的XML文件

 

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
                     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                     http://www.springframework.org/schema/context
                     http://www.springframework.org/schema/context/spring-context-3.0.xsd
                     http://www.springframework.org/schema/aop
                     http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
                     http://www.springframework.org/schema/tx
                     http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

	<context:annotation-config />

	<context:property-placeholder location="classpath:database.properties" />

	<bean id="userManager" class="main.spring.UserManagerImpl" />
	
	<anyotherWithoutNode></anyotherWithoutNode>

</beans>
 

运行结果:

 

2012-10-28 18:57:22,270 ERROR [main.xml.JAXPTest] - <cvc-complex-type.2.4.a: Invalid content starting with element 'anyotherWithoutNode'. The content must match '(("http://www.springframework.org/schema/beans":description){0-1},(("http://www.springframework.org/schema/beans":import)|("http://www.springframework.org/schema/beans":alias)|("http://www.springframework.org/schema/beans":bean)|(WC[##other:"http://www.springframework.org/schema/beans"]){0-UNBOUNDED}){0-UNBOUNDED})'.>
<context:annotation-config></context:annotation-config>
<context:property-placeholder ignore-resource-not-found="false" ignore-unresolvable="false" local-override="false" location="classpath:database.properties" system-properties-mode="FALLBACK"></context:property-placeholder>
<bean autowire="default" autowire-candidate="default" class="main.spring.UserManagerImpl" id="userManager" lazy-init="default"></bean>
<anyotherWithoutNode></anyotherWithoutNode>
 

 

 

 

 

 

分享到:
评论

相关推荐

    使用JAXP之SAX读取XML内容

    在计算机科学与技术领域,XML(可扩展标记语言)是一种重要的数据交换格式,常用于存储结构化数据。处理XML文档时,有多种解析方法,其中SAX...理解并熟练掌握SAX解析器的使用,对于提升XML处理能力有着重要作用。

    XML的Jaxp解析示例和简单项目

    XML(eXtensible Markup Language)是一种用于标记数据的语言,广泛应用在数据交换、配置文件、文档存储等领域。本文将深入探讨XML的解析方式之一——...通过理解和掌握JAXP,你可以更好地处理XML在实际项目中的应用。

    JAXP数据验证引擎 Serene

    xercesImpl.txt可能涉及Xerces-J,这是一个流行的XML解析器实现,经常与JAXP一起使用。 2. **LICENSE**:这是通用的许可证文件,可能涵盖了整个项目的许可信息。 3. **NOTICE.relaxng.datatype.txt, NOTICE....

    JAXP数据验证引擎 Serene.7z

    通过深入理解JAXP和Serene,开发者能够构建出健壮的XML处理系统,有效防止因数据格式错误导致的问题。 这个压缩包可能包含了Serene的库文件、示例代码、文档和配置文件等,帮助用户快速上手并使用这个强大的验证...

    基于Java的JAXP数据验证引擎 Serene.zip

    在这个名为“基于Java的JAXP数据验证引擎 Serene.zip”的压缩包中,我们可以推测它包含了一个使用Java实现的JAXP数据验证引擎——Serene。Serene可能是一个强大的工具,专注于XML文档的结构验证,确保它们符合预定义...

    XML_JAVA指南.rar_WORKING_java Tutorial_java xml_jaxp_xml

    "XML_JAVA指南.rar_WORKING_java Tutorial_java xml_jaxp_xml"这个资源可能包含了一个关于如何在Java项目中使用JAXP的教程。通常,这样的教程会涵盖如何创建XML文档,使用DOM和SAX解析XML,以及如何执行XSLT转换。它...

    基于Java的实例源码-JAXP数据验证引擎 Serene.zip

    通过分析这些文件,开发者可以学习到如何使用Java实现XML处理,理解JAXP的工作原理,研究Serene验证引擎的设计思路,以及如何进行XML数据验证。同时,也可以了解开源软件的许可证管理、项目构建流程和测试实践。

    使用jaxp进行dom解析_动力节点Java学院整理

    本文将详细介绍如何使用Java中的JAXP(Java API for XML Processing)来实现DOM解析,帮助开发者快速理解和掌握DOM解析技术。 首先,我们来了解一下JAXP。JAXP是Java提供的用于处理XML文档的一组API,主要包含两个...

    基于java的JAXP数据验证引擎 Serene.zip

    通过阅读和理解这个文件,开发者可以了解如何构建和管理Serene项目。 "testSuite"目录可能包含了Serene的数据验证测试用例,用于确保引擎的正确性。这些测试用例是重要的质量保证手段,通过运行它们,开发者可以...

    基于Java的实例开发源码-JAXP数据验证引擎 Serene.zip

    - 掌握Java编程,特别是JAXP API的使用。 - 熟悉Ant构建工具,能够阅读和理解`build.xml`脚本。 - 分析`testSuite`中的测试用例,理解Serene的验证过程。 通过研究Serene的源码,开发者可以深入理解XML数据验证...

    Jaxp_xml.rar_J2ME 程序_j2me_j2me xml_j2me 网络

    标题"Jaxp_xml.rar_J2ME程序_j2me_j2me_xml_j2me网络"表明这个压缩包包含了一个示例,演示如何使用JAXP(Java API for XML Processing)在J2ME环境中解析XML文件。JAXP是Java平台上的一个标准接口,用于处理XML文档...

    java源码:JAXP数据验证引擎 Serene.zip

    对于理解和使用Serene来说,这是一个重要的入口点。 3. build.xml: 这是一个Ant构建脚本,用于自动化构建过程,包括编译源代码、运行测试和打包工件。熟悉Ant或者Maven的用户可以利用这个文件来构建和运行项目。 4...

    基于Java的源码-JAXP数据验证引擎 Serene.zip

    DOM-software和SAX的许可证可能涉及它们使用的特定库,而`LICENSE.jaxp.txt`和`LICENSE.xercesImpl.txt`则可能与Java的XML处理API和Xerces实现有关。 2. `NOTICE.relaxng.datatype.txt`, `NOTICE.xercesImpl.txt`: ...

    Jaklin-OpenJDK-JAXP:(废弃)Jaklin repo https 的子模块

    这两个概念是 Java 开发中的重要组成部分,尤其是对于理解 Java 平台的核心功能而言。 1. **OpenJDK**: OpenJDK(开放源代码的 Java Development Kit)是 Java 虚拟机(JVM)和 Java 核心类库的一个开源实现。它...

    J2EE Web Services: XML SOAP WSDL UDDI WS-I JAX-RPC JAXR SAAJ JAXP

    **J2EE Web服务:XML、SOAP、WSDL、UDDI、WS-I、JAX-RPC、JAXR、SAAJ、JAXP详解** 在IT领域,尤其是在Java企业级应用开发中,Web服务扮演着至关重要的角色。J2EE(Java 2 Platform, Enterprise Edition)提供了一...

    解析JAXP

    **解析JAXP** JAXP,全称为Java API for XML Processing,是Java...理解和熟练使用JAXP,对于任何Java开发者来说,都是处理XML数据不可或缺的技能。在实际应用中,需要注意性能优化和安全防护,确保代码既高效又安全。

    jing-jaxp-test

    通过这个项目,开发者可以深入理解如何在Java环境中利用JAXP API和第三方工具Jing进行XML文件的验证,同时也能学习到如何编写和组织测试用例来确保代码的健壮性。这对于任何涉及XML处理的Java开发者来说都是宝贵的...

    JAXP数据验证引擎 Serene源码示例

    在"JAXP数据验证引擎Serene源码示例"中,我们可以深入理解Serene如何实现XML Schema的解析和验证过程。源码分析可以帮助开发者更好地掌握XML处理技术,了解JAXP的内部工作机制,并能够根据需求定制和优化XML验证流程...

    理解sax.doc 理解sax.doc

    - **XML解析器**:对于旧版本的Java,如Java 1.3.x,需要额外安装XML解析器,如Apache项目的Xerces-Java或Sun的Java API for XML Parsing (JAXP)。 - **其他语言**:SAX也可以在其他编程语言中使用,如C、C++、...

    Sun 的 Java API for XML 语法分析

    Java API for XML Processing,简称JAXP,是Sun Microsystems推出的一种用于处理XML的Java接口,旨在为XML解析提供一种统一的、与...理解和掌握JAXP的基本概念和使用方法,对于在Java环境中进行XML处理是非常关键的。

Global site tag (gtag.js) - Google Analytics