XML学习记录1-复习SAX,DOM和JAXB
对xml文档的解析常见的有JDK中的sax,dom,jaxb,stax和JAVA类库JDOM和DOM4J,下面先说说前三个。
Java中解析XML的工具很多,像JDOM,DOM4J等,但Java标准库提供的两种解析XML文档解析器是:DOM(Document Object Module)解析器 和 SAX(Simple API for XML)解析器。DOM解析器会读入整个XML文档并转换成树结构;SAX解析器会在读入XML文档时生成相应的事件;故也常叫基于文档对象模型的XML解析和基于事件驱动的XML解析;那它们有什么区别呢?
DOM解析器会读入整个文档,构建一个驻留在内存中的树型结构,我们就可以使用 DOM 接口来操作这个文档树,其优点是整个文档树在内存中,便于操作,支持删除、修改、重新排列等多种功能;缺点是需将整个文档读入内存中,在文档大时会消耗大量内存;
SAX解释器在XML文档读入时能够立即开始,而不是等待所有的数据加载完后处理,解析器通过发现元素开始、元素结束、文本开始、文档结束等来发送事件,通过种基于回调机制的方法来处理数据;其优点是解析速度快,不用事先调入整个文档,占用资源少;其缺点是必须实现事件处理程序,不能修改文档,不能随机访问。
JAXB(Java Architecture for XML Binding) 是一个业界的标准,是一项可以根据XML Schema产生Java类的技术。该过程中,JAXB也提供了将XML实例文档反向生成Java对象树的方法,并能将Java对象树的内容重新写到XML实例文档。从另一方面来讲,JAXB提供了快速而简便的方法将XML模式绑定到Java表示,从而使得Java开发者在Java应用程序中能方便地结合XML数据和处理函数。
- DOM(Document Object Model)
1.解析器工厂类:DocumentBuilderFactory
创建的方法:DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
2.解析器:DocumentBuilder
创建方法:通过解析器工厂类来获得 DocumentBuilder db = dbf.newDocumentBuilder();
3.文档树模型Document
创建方法:a.通过xml文档 Document doc = db.parse("bean.xml"); b.将需要解析的xml文档转化为输入流 InputStream is = new FileInputStream("bean.xml");
Document doc = db.parse(is);
Document对象代表了一个XML文档的模型树,所有的其他Node都以一定的顺序包含在Document对象之内,排列成一个树状结构,以后对XML文档的所有操作都与解析器无关,
直接在这个Document对象上进行操作即可;
包含的方法:
4.节点列表类NodeList
NodeList代表了一个包含一个或者多个Node的列表,根据操作可以将其简化的看做为数组
5.节点类Node
Node对象是DOM中最基本的对象,代表了文档树中的抽象节点。但在实际使用中很少会直接使用Node对象,而是使用Node对象的子对象Element,Attr,Text等
6.元素类Element
是Node类最主要的子对象,在元素中可以包含属性,因而Element中有存取其属性的方法
Node.getNamespaceURI() 返回和给定节点关联的名称空间字符串,如果该元素或属性没有关联的名称空间则返回 null。
7.属性类Attr
代表某个元素的属性,虽然Attr继承自Node接口,但因为Attr是包含在Element中的,但并不能将其看做是Element的子对象,因为Attr并不是DOM树的一部分
实例:
DomDemo.java
package dom; import java.io.File;
import java.io.FileInputStream;
import java.io.IOException; import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.EntityResolver;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException; public class DomDemo { public static void main(String[] args) throws Exception {
String url = System.getProperty("user.dir");
File xmlFile = new File(url + "/src/dom/beans.xml"); if(!xmlFile.exists())
{
System.out.println("file not exist, return.");
return;
} DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// 支持命名空间
dbf.setNamespaceAware(true);
// 开启校验
dbf.setValidating(true);
// 忽略注释
dbf.setIgnoringComments(true);
//如果使用xsd,一船需要设置schemaLanguage的schema版本.
dbf.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema"); try
{
DocumentBuilder db = dbf.newDocumentBuilder();
// 校验出错处理
db.setErrorHandler(new ErrorHandler() { @Override
public void warning(SAXParseException exception) throws SAXException {
System.out.println("warning: " + exception.getMessage()); } @Override
public void fatalError(SAXParseException exception) throws SAXException {
System.out.println("fatalError: " + exception.getMessage());
} @Override
public void error(SAXParseException exception) throws SAXException {
System.out.println("error: " + exception.getMessage());
}
}); // dtd 或者 schema 文件验证xml
// 校验xsd
db.setEntityResolver(new EntityResolver() { @Override
public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
String url = System.getProperty("user.dir");
InputSource inputSource = new InputSource(new FileInputStream(new File(url + "/bin/dom/spring-beans-3.2.xsd")));
inputSource.setSystemId(systemId);
inputSource.setPublicId(publicId);
return inputSource;
}
}); Document document = db.parse(xmlFile);
Element root = document.getDocumentElement();
System.out.println("根元素: " + root.getNodeName());
// 示例用法
/*NodeList childNodes = root.getChildNodes(); for(int i = 0; i <childNodes.getLength(); i++)
{
Node node = childNodes.item(i);
if("web-app".equals(node.getNodeName()))
{
System.out.println("\r\n找到一篇文章,所属分类: " + node.getAttributes()
.getNamedItem("category").getNodeValue() + ". ");
NodeList nodeDetail = node.getChildNodes();
for(int j = 0; j < nodeDetail.getLength(); j++)
{
Node detail = nodeDetail.item(j);
if("title".equals(detail.getNodeName()))
{
System.out.println("标题:" + detail.getTextContent());
}
else if("author".equals(detail.getNodeName()))
{
System.out.println("作者:" + detail.getTextContent());
}
else if("email".equals(detail.getNodeName()))
{
System.out.println("电子邮箱:" + detail.getTextContent());
}
else if("date".equals(detail.getNodeName()))
{
System.out.println("发表日期:" + detail.getTextContent());
}
}
}
}*/ }
catch(Exception exception)
{
exception.printStackTrace();
} } /**
* DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
* DocumentBuilder db = dbf.newDocumentBuilder();
* Document document = db.parse(xmlFile);
* Element root = document.getDocumentElement();
* NodeList childNodes = root.getChildNodes();
* Node node = childNodes.item(i);
* node.getAttributes();
* node.getAttributes().getNamedItem("category");
* detail.getNodeName();
* detail.getNodeValue();
* detail.getTextContent();
*
*/
}
beans.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <!-- 定义使用C3P0连接池的数据源 -->
<bean d="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!-- 指定连接数据库的JDBC驱动 -->
<property name="driverClass">
<value>com.mysql.jdbc.Driver</value>
</property>
<!-- 连接数据库所用的URL -->
<property name="jdbcUrl">
<value>jdbc:mysql://localhost:3306/eportal?useUnicode=true&characterEncoding=utf-8</value>
</property>
<!-- 连接数据库的用户名 -->
<property name="user">
<value>root</value>
</property>
<!-- 连接数据库的密码 -->
<property name="password">
<value>root</value>
</property>
<!-- 设置数据库连接池的最大连接数 -->
<property name="maxPoolSize">
<value>20</value>
</property>
<!-- 设置数据库连接池的最小连接数 -->
<property name="minPoolSize">
<value>2</value>
</property>
<!-- 设置数据库连接池的初始化连接数 -->
<property name="initialPoolSize">
<value>2</value>
</property>
<!-- 设置数据库连接池的连接的最大空闲时间,单位为秒 -->
<property name="maxIdleTime">
<value>20</value>
</property>
</bean> <!-- 定义Hibernate的SessionFactory -->
<bean id="sessionFactory"
class="org.springframework.orm.
hibernate3.LocalSessionFactoryBean">
<!-- 依赖注入上面定义的数据源dataSource -->
<property name="dataSource" ref="dataSource" />
<!-- 注册Hibernate的ORM映射文件 -->
<property name="mappingResources">
<list>
<value>com/eportal/ORM/News.hbm.xml</value>
<value>com/eportal/ORM/Category.hbm.xml</value>
<value>com/eportal/ORM/Memberlevel.hbm.xml</value>
<value>com/eportal/ORM/Cart.hbm.xml</value>
<value>com/eportal/ORM/Traffic.hbm.xml</value>
<value>com/eportal/ORM/Newsrule.hbm.xml</value>
<value>com/eportal/ORM/Merchandise.hbm.xml</value>
<value>com/eportal/ORM/Admin.hbm.xml</value>
<value>com/eportal/ORM/Orders.hbm.xml</value>
<value>com/eportal/ORM/Cartselectedmer.hbm.xml</value>
<value>com/eportal/ORM/Newscolumns.hbm.xml</value>
<value>com/eportal/ORM/Member.hbm.xml</value>
</list>
</property>
<!-- 设置Hibernate的相关属性 -->
<property name="hibernateProperties">
<props>
<!-- 设置Hibernate的数据库方言 -->
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<!-- 设置Hibernate是否在控制台输出SQL语句,开发调试阶段通常设为true -->
<prop key="show_sql">true</prop>
<!-- 设置Hibernate一个提交批次中的最大SQL语句数 -->
<prop key="hibernate.jdbc.batch_size">50</prop>
<prop key="show_sql">50</prop>
</props>
</property>
</bean>
<!--定义Hibernate的事务管理器HibernateTransactionManager -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<!-- 依赖注入上面定义的sessionFactory -->
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!--定义Spring的事务拦截器TransactionInterceptor -->
<bean id="transactionInterceptor"
class="org.springframework.transaction.interceptor.TransactionInterceptor">
<!-- 依赖注入上面定义的事务管理器transactionManager -->
<property name="transactionManager" ref="transactionManager" />
<!-- 定义需要进行事务拦截的方法及所采用的事务控制类型 -->
<property name="transactionAttributes">
<props>
<!-- 以browse、list、load、get及is开头的所有方法采用只读型事务控制类型 -->
<prop key="browse*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="list*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="load*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="is*">PROPAGATION_REQUIRED,readOnly</prop>
<!-- 所有方法均进行事务控制,如果当前没有事务,则新建一个事务 -->
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
<!-- 定义BeanNameAutoProxyCreatorf进行Spring的事务处理 -->
<bean
class="org.springframework.aop.framework.autoproxy.
BeanNameAutoProxyCreator">
<!-- 针对指定的bean自动生成业务代理 -->
<property name="beanNames">
<list>
<value>adminService</value>
<value>columnsService</value>
<value>newsService</value>
<value>crawlService</value>
<value>memberLevelService</value>
<value>memberService</value>
<value>categoryService</value>
<value>merService</value>
<value>cartService</value>
<value>ordersService</value>
<value>trafficService</value>
</list>
</property>
<!-- 这个属性为true时,表示被代理的是目标类本身而不是目标类的接口 -->
<property name="proxyTargetClass">
<value>true</value>
</property>
<!-- 依赖注入上面定义的事务拦截器transactionInterceptor -->
<property name="interceptorNames">
<list>
<value>transactionInterceptor</value>
</list>
</property>
</bean>
<!-- 装配通用数据库访问类BaseDAOImpl -->
<bean id="dao" class="com.eportal.DAO.BaseDAOImpl">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- 部署系统用户管理业务逻辑组件AdminServiceImpl -->
<bean id="adminService" class="com.eportal.service.AdminServiceImpl">
<property name="dao" ref="dao" />
</bean>
<!-- 部署新闻栏目管理业务逻辑组件ColumnsServiceImpl -->
<bean id="columnsService" class="com.eportal.service.ColumnsServiceImpl">
<property name="dao" ref="dao" />
</bean> <!-- 部署订单管理业务逻辑组件OrderServiceImpl -->
<bean id="ordersService" class="com.eportal.service.OrderServiceImpl">
<property name="dao" ref="dao" />
</bean>
<!-- 部署流量统计业务逻辑组件TrafficServiceImpl -->
<bean id="trafficService" class="com.eportal.service.TrafficServiceImpl">
<property name="dao" ref="dao" />
</bean>
<!-- 部署Struts 2负责系统用户管理的控制器AdminAction -->
<bean id="adminAction" class="com.eportal.struts.action.
AdminAction"
scope="prototype">
<property name="service" ref="adminService" />
</bean>
<!-- 部署Struts 2负责新闻栏目管理的控制器ColumnsAction -->
<bean id="columnsAction" class="com.eportal.struts.action.
ColumnsAction"
scope="prototype">
<property name="service" ref="columnsService" />
</bean>
<!-- 部署Struts 2负责新闻管理的控制器NewsAction -->
<bean id="newsAction" class="com.eportal.struts.action.
NewsAction"
scope="prototype">
<property name="service" ref="newsService" />
<property name="columnsService" ref="columnsService" />
</bean>
<!-- 部署Struts 2负责新闻采集规则管理的控制器CrawlAction -->
<bean id="crawlAction" class="com.eportal.struts.action.
CrawlAction"
scope="prototype">
<property name="service" ref="crawlService" />
<property name="columnsService" ref="columnsService" />
</bean> </beans>
spring-beans-3.2.xsd(只显示一部分)
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- 注释掉了property -->
<xsd:schema xmlns="http://www.springframework.org/schema/beans"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.springframework.org/schema/beans"> <xsd:import namespace="http://www.w3.org/XML/1998/namespace"/> <xsd:annotation>
<xsd:documentation><![CDATA[
Spring XML Beans Schema, version 3.2
Authors: Juergen Hoeller, Rob Harrop, Mark Fisher, Chris Beams This defines a simple and consistent way of creating a namespace
of JavaBeans objects, managed by a Spring BeanFactory, read by
XmlBeanDefinitionReader (with DefaultBeanDefinitionDocumentReader). This document type is used by most Spring functionality, including
web application contexts, which are based on bean factories. Each "bean" element in this document defines a JavaBean.
Typically the bean class is specified, along with JavaBean properties
and/or constructor arguments. A bean instance can be a "singleton" (shared instance) or a "prototype"
(independent instance). Further scopes can be provided by extended
bean factories, for example in a web environment. References among beans are supported, that is, setting a JavaBean property
or a constructor argument to refer to another bean in the same factory
(or an ancestor factory). As alternative to bean references, "inner bean definitions" can be used.
Singleton flags of such inner bean definitions are effectively ignored:
inner beans are typically anonymous prototypes. There is also support for lists, sets, maps, and java.util.Properties
as bean property types or constructor argument types.
]]></xsd:documentation>
</xsd:annotation> <!-- base types -->
<xsd:complexType name="identifiedType" abstract="true">
<xsd:annotation>
<xsd:documentation><![CDATA[
The unique identifier for a bean. The scope of the identifier
is the enclosing bean factory.
]]></xsd:documentation>
</xsd:annotation>
<xsd:attribute name="id" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The unique identifier for a bean. A bean id may not be used more than once
within the same <beans> element.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType> <!-- Top-level <beans> tag -->
<xsd:element name="beans">
<xsd:annotation>
<xsd:documentation><![CDATA[
Container for <bean> and other elements, typically the root element in the document.
Allows the definition of default values for all nested bean definitions. May itself
be nested for the purpose of defining a subset of beans with certain default values or
to be registered only when certain profile(s) are active. Any such nested <beans> element
must be declared as the last element in the document.
]]></xsd:documentation>
</xsd:annotation>
。。。。。。
。。。。。。
。。。。。。
。。。。。。
</xsd:schema>
包含了对xml文件的验证和错误处理。验证使用EntityResolver,错误处理使用ErrorHandler,和基本使用示例
下面说一下DOM方式生成XML:抄了一段别人的代码:
package util; import java.io.File; 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.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult; import org.w3c.dom.Document;
import org.w3c.dom.Element; public class FileUtil { public void createXMLByDOM(File dest) {
// 创建DocumentBuilderFactory
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try { // 创建DocumentBuilder
DocumentBuilder builder = factory.newDocumentBuilder(); // 创建Document
Document document = builder.newDocument(); // 设置XML声明中standalone为yes,即没有dtd和schema作为该XML的说明文档,且不显示该属性
// document.setXmlStandalone(true); // 创建根节点
Element bookstore = document.createElement("bookstore"); // 创建子节点,并设置属性
Element book = document.createElement("book");
book.setAttribute("id", "1"); // 为book添加子节点
Element name = document.createElement("name");
name.setTextContent("安徒生童话");
book.appendChild(name);
Element author = document.createElement("author");
author.setTextContent("安徒生");
book.appendChild(author);
Element price = document.createElement("price");
price.setTextContent("49");
book.appendChild(price); // 为根节点添加子节点
bookstore.appendChild(book); // 将根节点添加到Document下
document.appendChild(bookstore); /*
* 下面开始实现: 生成XML文件
*/ // 创建TransformerFactory对象
TransformerFactory tff = TransformerFactory.newInstance(); // 创建Transformer对象
Transformer tf = tff.newTransformer(); // 设置输出数据时换行
tf.setOutputProperty(OutputKeys.INDENT, "yes"); // 使用Transformer的transform()方法将DOM树转换成XML
tf.transform(new DOMSource(document), new StreamResult(dest)); } catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (TransformerConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TransformerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} } }
详见下面的文章:Java——DOM方式生成XML
2. SAX (Simple API for XML)
SAX是基于事件的方法,它很类似于标签库的处理机制,在文档开始、结束,标签开始、结束以及错误发生等等地方调用相应的接口实现方法,不是全部文 档都读入内存。 SAX具有优异的性能和利用更少的存储空间特点。SAX 的设计只考虑了功能的强大性,却没有考虑程序员使用起来是否方便。
必须扩展ContentHandler(或者DefaultHandler )。
实例:
package sax; import java.io.File; import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory; public class SaxDemo {
public static void main(String[] args) throws Exception {
String url = System.getProperty("user.dir");
File xmlFile = new File(url + "/src/sax/article.xml");
if(!xmlFile.exists())
{
System.out.println("file not found, return");
return;
} SAXParserFactory spf = SAXParserFactory.newInstance();
// Specifies that the parser produced by this code will provide support for XML namespaces
spf.setNamespaceAware(true);
spf.setValidating(true);
// http://blog.csdn.net/scmrpu/article/details/50423701
spf.setFeature("http://xml.org/sax/features/validation", true); try
{
SAXParser sp = spf.newSAXParser();
sp.parse(xmlFile, new MySaxHandler());
}
catch(Exception e)
{
e.printStackTrace();
}
} /**
* SAXParserFactory spf = SAXParserFactory.newInstance();
* SAXParser sp = spf.newSAXParser();
* sp.parse(xmlFile, new MySaxHandler());
* MySaxHandler
* startElement
* endElement
* endDocument
* startDocument
* characters
*/
}
article.xml
<?xml version="1.0" encoding="UTF-8"?>
<a:articles xmlns:a="www.example.namespace/article">
<a:article category="java">
<a:title>Java基本语法</a:title>
<a:author>janet</a:author>
<a:email>janetvsfei@yahoo.com.cn</a:email>
<a:date>20080801</a:date>
</a:article>
<a:article category="xml">
<a:title>XML概述</a:title>
<a:author>janet</a:author>
<a:email>janetvsfei@yahoo.com.cn</a:email>
<a:date>20080801</a:date>
</a:article>
</a:articles>
MySaxHandler.java
package sax; import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler; public class MySaxHandler extends DefaultHandler { private String content;
@Override
public void startDocument() throws SAXException
{
} @Override
public void endDocument() throws SAXException
{
} @Override
/*
*spf.setNamespaceAware(true): then uri and localName are not null; otherwise
*they are null.
*/
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException
{
if("a:article".equals(qName))
{
System.out.println("\r\n找到一篇文章,所属分类: " + attributes.getValue("category") + ". ");
}
} @Override
public void endElement(String uri, String localName, String qName) throws SAXException
{
if("a:title".equals(qName))
{
System.out.println("标题:" + content);
}
else if("a:author".equals(qName))
{
System.out.println("作者:" + content);
}
else if("a:email".equals(qName))
{
System.out.println("电子邮箱:" + content);
}
else if("a:date".equals(qName))
{
System.out.println("发表日期:" + content);
}
} @Override
public void characters(char[] ch, int start, int length) throws SAXException
{
content = new String(ch, start, length);
}
}
下面是SAX生成XML,抄了别人一段代码:
package util; import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult; import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl; import domain.Book; public class XMLUtil { private List<Book> bookList; //生成XML文件
public void createXMLBySAX(List<Book> books, File dest) {
// 创建SAXTransformerFactory对象
SAXTransformerFactory factory = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
try {
// 通过SAXTransformerFactory对象创建TransformerHandler对象
TransformerHandler handler = factory.newTransformerHandler();
// 通过Handler创建Transformer对象
Transformer transformer = handler.getTransformer();
// 设置Transformer的属性
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
// 创建Result对象,并将目的XML文件与其关联
Result result = new StreamResult(dest);
// 将handler与result关联起来
handler.setResult(result); try {
// 开启文档
handler.startDocument();
// 新建节点
handler.startElement("", "", "bookstore", null);
AttributesImpl atts = new AttributesImpl();
for (Book book : books) {
atts.clear();
atts.addAttribute("", "", "id", "", String.valueOf(book.getId()));
handler.startElement("", "", "book", atts);
handler.startElement("", "", "name", null);
handler.characters(book.getName().toCharArray(), 0, book.getName().length());
handler.endElement("", "", "name");
handler.startElement("", "", "author", null);
handler.characters(book.getAuthor().toCharArray(), 0, book.getAuthor().length());
handler.endElement("", "", "author");
handler.startElement("", "", "price", null);
handler.characters(Float.toString(book.getPrice()).toCharArray(), 0,
Float.toString(book.getPrice()).length());
handler.endElement("", "", "price");
handler.endElement("", "", "book");
}
// 关闭节点
handler.endElement("", "", "bookstore");
// 关闭文档
handler.endDocument();
} catch (SAXException e) {
e.printStackTrace();
} } catch (TransformerConfigurationException e) {
e.printStackTrace();
}
} //解析XML文件
public List<Book> parseXMLBySAX(File file) {
SAXParser parser = getParser();
MyHandler handler = new MyHandler();
try {
parser.parse(file, handler);
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
bookList = handler.getBookList(); return bookList;
} public SAXParser getParser() {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = null;
try {
parser = factory.newSAXParser();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
}
return parser;
} public List<Book> getBookList() {
return bookList;
} public void setBookList(List<Book> bookList) {
this.bookList = bookList;
} }
详见下面的文章:Java——SAX方式生成XML
3. JAXB(Java Architecture for XML Binding)
JAXB(Java Architecture for XML Binding) 是一个业界的标准,是一项可以根据XML Schema产生Java类的技术。该过程中,JAXB也提供了将XML实例文档反向生成Java对象树的方法,并能将Java对象树的内容重新写到XML实例文档。从另一方面来讲,JAXB提供了快速而简便的方法将XML模式绑定到Java表示,从而使得Java开发者在Java应用程序中能方便地结合XML数据和处理函数。
实例:
基本的java bean的处理
package jaxb; import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.StringWriter; import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller; public class JAXBDemo {
public static void main(String[] args) {
String url = System.getProperty("user.dir");
File xmlFile = new File(url + "/src/jaxb/article.xml");
if(xmlFile.exists())
{
xmlFile.delete();
} JAXBContext jaxbContext;
BufferedWriter bw = null; try
{
jaxbContext = JAXBContext.newInstance(Article.class);
// marshal
Marshaller m = jaxbContext.createMarshaller();
m.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");// 设置编码
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);// 格式化输出 Article article = new Article();
article.setAuthor("Janet");
article.setDate("20080801");
article.setEmail("janetvsfei@yhoo.com.cn");
article.setTitle("XML"); StringWriter sw = new StringWriter();
xmlFile.createNewFile(); // 生成xml
m.marshal(article, sw); bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(xmlFile)));
bw.write(sw.toString().replace(" standalone=\"yes\"", ""));// 去掉standalone属性
if(null != bw)
{
bw.close();
} // unmarshal
Unmarshaller u = jaxbContext.createUnmarshaller(); // 从xml生成java对象
Article article2 = (Article) u.unmarshal(xmlFile);
System.out.println(article2);
}
catch(Exception e)
{
e.printStackTrace();
}
} /**
* JAXBContext jaxbContext = JAXBContext.newInstance(Article.class);
* Marshaller m = jaxbContext.createMarshaller();
* m.marshal(article, sw);
*
* Unmarshaller u = jaxbContext.createUnmarshaller();
* Article article2 = (Article) u.unmarshal(xmlFile);
*/
}
article.xml
<?xml version="1.0" encoding="UTF-8"?>
<article>
<author>Janet</author>
<date>20080801</date>
<email>janetvsfei@yahoo.com.cn</email>
<title>XML</title>
</article>
列表的处理
package jaxb; import java.io.File;
import java.util.ArrayList;
import java.util.List; import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlRootElement; // root name
@XmlRootElement(name="articles")
public class ArticleData {
// named root's first level children list name
private List<Article> article = new ArrayList<Article>(); public List<Article> getArticle() {
return article;
}
public void setArticle(List<Article> article) {
this.article = article;
}
public static void main(String[] args) {
String url = System.getProperty("user.dir");
File xmlFile = new File(url + "/src/jaxb/article2.xml");
JAXBContext jaxbContext;
try
{
jaxbContext = JAXBContext.newInstance(ArticleData.class);
Unmarshaller u = jaxbContext.createUnmarshaller();
ArticleData articleData = (ArticleData) u.unmarshal(xmlFile); System.out.println(articleData.getArticle().get(0));
System.out.println(articleData.getArticle().get(1));
}
catch(Exception e)
{
e.printStackTrace();
}
} }
article2.xml
<?xml version="1.0" encoding="UTF-8"?>
<articles>
<article category="java">
<title>Java基本语法</title>
<author>janet</author>
<email>janetvsfei@yahoo.com.cn</email>
<date>20080801</date>
</article>
<article category="xml">
<title>XML概述</title>
<author>janet</author>
<email>janetvsfei@yahoo.com.cn</email>
<date>20080801</date>
</article>
</articles>
Article.java
package jaxb; import javax.xml.bind.annotation.XmlRootElement;
// 使用注解
@XmlRootElement
public class Article {
private String title;
private String author;
private String email;
private String date; @Override
public String toString() {
return "Article [title=" + title + ", author=" + author + ", email=" + email + ", date=" + date + "]";
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
}
详细内容可以看下面的文章:JAXB应用实例
除了抄别人的代码,剩下的都是自己学习过程的代码,对dom,说了解析xml,设置错误处理器和校验,还说了生成xml(抄别人的代码);对sax,说了生成(抄别人的代码)与解析xml;对JAXB,说了生成与解析XML,还说了字段为列表的情况,其它内容可以看我提供的文章,有关于jaxb更高级一些的内容,如适配器,工具类,更多注解,数据修改,对集合与对象字段的处理,自己学习的很浅显,看别人的文章才能看出问题,只当是做个大致的了解,作为入门的参考吧。
XML学习记录1-复习SAX,DOM和JAXB的更多相关文章
- Android学习笔记_7_使用 sax 或者 dom 或者 pull 解析XML文件
一.Pull解析介绍: Android上使用SAX和DOM方式解析XML的方法,并且对两种做了简单的比较,通过比较我们知道对在往往内存比较稀缺的移动设备上运行的Android系统来说,SAX是一种比较 ...
- java操作xml方式比较与详解(DOM、SAX、JDOM、DOM4J)
java中四种操作(DOM.SAX.JDOM.DOM4J)xml方式的比较与详解 1)DOM(JAXP Crimson解析器) DOM是用与平台和语言无关的方式表示XML文档的官方W3C标准. ...
- DOM解析xml学习笔记
一.dom解析xml的优缺点 由于DOM的解析方式是将整个xml文件加载到内存中,转化为DOM树,因此程序可以访问DOM树的任何数据. 优点:灵活性强,速度快. 缺点:如果xml文件比较大比较复杂会占 ...
- Android XML文档解析(一)——SAX解析
---------------------------------------------------------------------------------------------------- ...
- XML学习教程
XML学习进阶1-- 什么是XML. 为什么使用 XML?... 什么是 XML?... 数据的结构表示... XML 文档... 数据是从表示和处理中分离出来的... 使XML数据自描述... XM ...
- XML学习(一)
本文主要记录xml学习过程中的一些笔记,包括xml作用,语法以及解析. 1.HTML和XML的区别 1.1.HTML 名称: HyperText Markup Languae(超文本标记语言) ...
- XML学习笔记(2)--dom4j操作XML
1. 介绍(四种方式的比较这部分转载自:http://www.blogjava.net/xcp/archive/2010/02/12/312617.html) 1)DOM(JAXP Crimson解析 ...
- D3.js学习记录【转】【新】
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 前端学习记录之Javascript-DOM
简介 为了快捷方便,在工作和项目中,一直都是使用的框架,比如jqeruy,vuejs,react等.然后在长时间使用框架后,往往有一个后遗症,就是对于原生的Javascript基本上已经不知道怎么写了 ...
随机推荐
- Oracle ADDM性能诊断利器及报告解读
性能优化是一个永恒的话题,性能优化也是最具有价值,最值得花费精力深入研究的一个课题,因为资源是有限的,时间是有限的.在Oracle数据库中,随着Oracle功能的不断强大和完善,Oralce数据库在性 ...
- 未能正确加载“VSTS for Database Professionals Sql Server Data-tier Application”包。(转)
今天费了九牛二虎之力,重转好了vs2010之后,打开解决方案,报出下面的错误: ---------------------------Microsoft Visual Studio---------- ...
- HttpPostedFile类
在研究HttpRequest的时候,搞文件上传的时候,经常碰到返回HttpPostedFile对象的情况,这个对象才是真正包含文件内容的东西. 经常要获取的最重要的内容是FileName属性与Sava ...
- [C++ Primer] : 第14章: 重载运算符与类型转换
基本概念 重载运算符是具有特殊名字的函数: 它们的名字由关键字operator和其后要定义的运算符号共同组成. 重载运算符函数的参数数量与该运算符作用的运算对象数量一样多. 对于二元运算符来说, 左侧 ...
- C# 使用OLEDB读取不同版本Excel数据的连接字符串
用OLEDB通过设置连接字符串可以像读取sqlserver一样将excel中的数据读取出来,但是excel2003和excel2007/2010的连接字符串是不同的 /// <summary&g ...
- 【Hibernate异常处理-1】java.lang.NoSuchMethodError: javax.persistence.JoinColumn.foreignKey()Ljavax/persistence/ForeignKey;
原文链接(经验证正确) 说明:其他几个涉及到:NoSuchMethodError: javax.persistence.xxx的处理方法和这相同. JAVAEE6.0中的 javax.persist ...
- 源码|ThreadLocal的实现原理
ThreadLocal也叫"线程本地变量"."线程局部变量": 其作用域覆盖线程,而不是某个具体任务: 其"自然"的生命周期与线程的生命周期 ...
- bzoj3685 普通veb树
Description 设计数据结构支持: 1 x 若x不存在,插入x 2 x 若x存在,删除x 3 输出当前最小值,若不存在输出-1 4 输出当前最大值,若不存在输出-1 5 x ...
- 显式等待大结局___封装成API方便控制层调用
控制层 测试用例层: 控制层示例代码: #coding=utf-8from selenium.webdriver.common.by import Byfrom selenium.webdriver. ...
- 学习笔记之100 TOP Ikm C++ Online Test Questions
100 TOP Ikm C++ Online Test Questions 2017 http://interviewquestionstutorials.com/tag/100-top-ikm-c- ...