spring源码附录(1)java实现对XML格式的验证
来源:互联网 发布:淘宝品牌调性分怎么查 编辑:程序博客网 时间:2024/05/22 16:05
最近在看spring源码,涉及到xml文档的解析、xml文档的格式验证,发现自己对xml解析的基础较为薄弱,本篇博客复习下DOM方式解析xml(即spring解析xml的方式)。
DOM解析XML是将整个XML作为一个对象,占用内存较多。另外一个java官方的XML解析方式SAX是边扫描边解析,自顶向下依次解析,占用内存较少。
一、java实现对XML格式的验证
可以使用两种验证模式(DTD、XSD)保证XML文件格式正确,DTD和XSD均是XML约束描述语言,是XML文件的验证机制。本文以DTD为例。
DTD文件格式请参考:http://www.cnblogs.com/zhengcheng/p/4278899.html
看下面student.xml:
<?xml version="1.0"?><!DOCTYPE 学生名册 SYSTEM "student.dtd"><学生名册> <学生 学号="t1"> <姓名>张三</姓名> <性别>男</性别> <年龄>20</年龄> </学生> <学生 学号="t2"> <姓名>李四</姓名> <性别>女</性别> <年龄>19</年龄> </学生></学生名册>
我们看到上面这个XML指定的DTD验证文件为student.dtd:
<?xml version="1.0" encoding="UTF-8"?><!ELEMENT 学生名册 (学生*)><!ELEMENT 学生 (姓名,性别,年龄)><!ELEMENT 姓名 (#PCDATA)><!ELEMENT 性别 (#PCDATA)><!ELEMENT 年龄 (#PCDATA)><!ATTLIST 学生 学号 ID #REQUIRED>
那么java DOM解析XML如何实现验证?
下面使用DOM解析student.xml:
public class test { public static void main(String[] args) { DocumentBuilderFactory buildFactory = DocumentBuilderFactory.newInstance(); //开启XML格式验证 buildFactory.setValidating(true); try { DocumentBuilder build = buildFactory.newDocumentBuilder(); //指定验证出错处理类MyErrorHandle build.setErrorHandler(new MyErrorHandler()); //自定义解析方式,如果不设置,则使用默认实现 build.setEntityResolver(new MyResolveEntity()); Document doc = build.parse("student.xml"); getStudents(doc); } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } private static void getStudents(Document doc) { Element root = doc.getDocumentElement(); NodeList nodeList = root.getElementsByTagName("学生"); for(int i=0;i<nodeList.getLength();i++){ Node node = nodeList.item(i); NamedNodeMap map = node.getAttributes(); System.out.println(map.item(0).getTextContent()); //子节点 NodeList childList = node.getChildNodes(); for(int j=0;j<childList.getLength();j++){ Node childNode = childList.item(j); System.out.println(childNode.getTextContent()); } } }}public class MyErrorHandler implements ErrorHandler{ @Override public void warning(SAXParseException exception) throws SAXException { // TODO Auto-generated method stub } @Override public void error(SAXParseException exception) throws SAXException { System.out.println("发生了错误!"+exception.getMessage()); } @Override public void fatalError(SAXParseException exception) throws SAXException { // TODO Auto-generated method stub }}public class MyResolveEntity implements EntityResolver{ @Override public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException { return new InputSource("student.dtd"); //return null; }}
如果不设置setEntityResolver,则会使用XML中指定位置的DTD文件进行验证,
<!DOCTYPE 学生名册 SYSTEM "student.dtd">
student.dtd即指定了验证文件的位置。
二、spring源码中对XML文件的验证的处理
在spring中,为网络地址:
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
publicId:-//SPRING//DTD BEAN//EN
systemId:http://www.springframework.org/dtd/spring-beans.dtd
如果设置了setEntityResolver,则会按照EntityResolver进行XML验证:先去项目中寻找spring-beans.xsd,如果未获取到则按照网络地址寻找。
以spring中 Spring-beans.dtd为例:
public class BeansDtdResolver implements EntityResolver {
private static final String DTD_EXTENSION = ".dtd"; private static final String DTD_NAME = "spring-beans"; private static final Log logger = LogFactory.getLog(BeansDtdResolver.class); @Override public InputSource resolveEntity(String publicId, String systemId) throws IOException { if (logger.isTraceEnabled()) { logger.trace("Trying to resolve XML entity with public ID [" + publicId + "] and system ID [" + systemId + "]"); } if (systemId != null && systemId.endsWith(DTD_EXTENSION)) { int lastPathSeparator = systemId.lastIndexOf("/"); int dtdNameStart = systemId.indexOf(DTD_NAME, lastPathSeparator); if (dtdNameStart != -1) { String dtdFile = DTD_NAME + DTD_EXTENSION; if (logger.isTraceEnabled()) { logger.trace("Trying to locate [" + dtdFile + "] in Spring jar on classpath"); } try { Resource resource = new ClassPathResource(dtdFile, getClass()); InputSource source = new InputSource(resource.getInputStream()); source.setPublicId(publicId); source.setSystemId(systemId); if (logger.isDebugEnabled()) { logger.debug("Found beans DTD [" + systemId + "] in classpath: " + dtdFile); } return source; } catch (IOException ex) { if (logger.isDebugEnabled()) { logger.debug("Could not resolve beans DTD [" + systemId + "]: not found in classpath", ex); } } } } // Use the default behavior -> download from website or wherever. return null; }}
- spring源码附录(1)java实现对XML格式的验证
- spring源码附录(3)容器的基本实现
- spring源码附录(8)import、beans标签的解析
- spring源码附录(4)FactoryBean的使用
- 附录1 利用V C的MCIWnd控件实现对AVI格式多媒体文件的实时调用
- spring源码附录(5)spring源码中使用到的设计模式
- spring源码附录(2)spring profile属性的简单使用
- Java Thread 源码 附录
- spring源码附录(5)解析子元素constructor-arg
- spring源码附录(6)解析子元素property
- Spring源码深度解析(六)获取XML的验证模式
- 【Spring源码从入门到精通】 (六)获取XML的验证模式
- Spring源码深度解析(六)获取XML的验证模式
- java中使用正则对格式的验证
- java,javascript对18位身份证格式的验证算法
- java,javascript对18位身份证格式的验证算法
- Xsd文件验证xml的java实现
- xsd文件验证xml的java实现
- 51Nod-1182 完美字符串【排序+字符统计】
- Ensemble Learning-模型融合-Python实现
- 同源策略和跨域访问
- JavaScript将input file的选择的文件清空的两种解决方案
- All sentinels down, cannot determine where is mymaster master is running
- spring源码附录(1)java实现对XML格式的验证
- 基本算法之堆排序
- hdu_round3-1003.bx回文(manacher+dp)
- git常用命令
- jstl fmt标签笔记
- 华为机试——明明的随机数
- Linux常用命令清单
- 用多线程进行的序列快速排序
- 51 nod 1212 基础MST