Spring读取xml文件[schema/dtd]

主测试类如下:
说明
[list]
[*] 使用了ErrorHandler,主要是把异常信息接到我们常用的日志信息中
[*] 使用了EntityResolver,实体解析类,主要解决xml中publicId对应的schema/dtd.
[*] 设置了DocumentBuilderFactory,主要设置名称空间,是否验证schema/dtd
[*] 建立META-INF/myschema.schemas,指定命名空间对应的xsd/dtd实际的路径[本地或网络]
[/list]

package org.frame.base.xml.jdk.bk;

import java.io.IOException;
import java.io.StringReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.frame.base.xml.jdk.ContactName;
import org.frame.base.xml.jdk.MaySimpleSaxErrorHandler;
import org.frame.base.xml.jdk.MyPluggableSchemaResolver;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.EntityResolver;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
* xml reader
*
* this example is from spring code.
* @see spring XmlBeanDefinitionReader
*
* @author ycl
* @version 1.0 2012-12-11 下午2:06:55
* @since 1.0
*
*/
public class TestDocumentBuilderFactory {

protected final static Log logger = LogFactory.getLog(TestDocumentBuilderFactory.class);

public static void main(String[] args) {

//set jaxp debug
System.setProperty("jaxp.debug","1");
DocumentBuilderFactory builderFactory = DocumentBuilderFactory
.newInstance();

//设置使用命名空间
builderFactory.setNamespaceAware(true);
builderFactory.setValidating(true);
builderFactory.setIgnoringComments(true);
builderFactory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema");
//如果使用xsd,一船需要设置schemaLanguage的schema版本.

ErrorHandler errorHandler = new MaySimpleSaxErrorHandler(logger);
//异常处理类
EntityResolver entityResolver = new MyPluggableSchemaResolver(TestDocumentBuilderFactory.class.getClassLoader());
//实体分解类

Document document = parse(builderFactory,getInputSource(),entityResolver,errorHandler);

print(document);

}

private static void print(Document document){
Element root = document.getDocumentElement();

List<ContactName> contactNameList = new ArrayList<ContactName>();

ContactName contactItem;

// 子元素列表
NodeList nodes = root.getChildNodes();

/**
* code this is so tied.
*/
for (int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
if (node instanceof Element) {
// a child element to process
Element child = (Element) node;
String width = child.getAttribute("width");
contactItem = new ContactName();
contactItem.setWidth(width);
NodeList itemSub = node.getChildNodes();
for (int j = 0; j < itemSub.getLength(); j++) {
Node itemSubNode = itemSub.item(j);
if (itemSubNode instanceof Element) {
if(((Element) itemSubNode).getTagName().equals("uic")){
contactItem.setUid(itemSubNode.getTextContent());
}else if(((Element) itemSubNode).getTagName().equals("fullName")){
contactItem.setFullName(itemSubNode.getTextContent());
}
}
}
contactNameList.add(contactItem);
}
}
System.out.println(contactNameList);
}

private static InputSource getInputSource(){
StringBuffer xml = new StringBuffer(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
xml.append("<contact xmlns=\"http://www.ycl.com/schema/schema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.ycl.com/schema/schema http://www.ycl.com/schema/schema.xsd\" >");
xml.append("<!--ycl is good -->");
xml.append("<item width=\"10\">");
xml.append("<uic>1</uic>");
xml.append("<fullName>ycl1</fullName>");
xml.append("</item>");

xml.append("<item width=\"11\">");
xml.append("<uic>1 <![CDATA[06:00 Vesti<br>06:05 Jutarnji]]> 2</uic>");
xml.append("<fullName>ycl2</fullName>");
xml.append("</item>");

xml.append("</contact>");

InputSource is = new InputSource(new StringReader(xml.toString()));
return is;
}

private static Document parse(DocumentBuilderFactory builderFactory,InputSource is,EntityResolver entityResolver, ErrorHandler errorHandler) {
DocumentBuilder builder = null;

Document document = null;
try {
builder = builderFactory.newDocumentBuilder();
if (entityResolver != null) {
builder.setEntityResolver(entityResolver);
}
if (errorHandler != null) {
builder.setErrorHandler(errorHandler);
}
document = builder.parse(is);
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return document;
}
}




package org.frame.base.xml.jdk;

import org.apache.commons.logging.Log;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

public class MaySimpleSaxErrorHandler implements ErrorHandler {

private final Log logger;


/**
* Create a new SimpleSaxErrorHandler for the given
* Commons Logging logger instance.
*/
public MaySimpleSaxErrorHandler(Log logger) {
this.logger = logger;
}


public void warning(SAXParseException ex) throws SAXException {
logger.warn("Ignored XML validation warning", ex);
}

public void error(SAXParseException ex) throws SAXException {
throw ex;
}

public void fatalError(SAXParseException ex) throws SAXException {
throw ex;
}

}




package org.frame.base.xml.jdk;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.xml.PluggableSchemaResolver;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

public class MyPluggableSchemaResolver implements EntityResolver {

/**
* The location of the file that defines schema mappings.
* Can be present in multiple JAR files.
*/
public static final String DEFAULT_SCHEMA_MAPPINGS_LOCATION = "META-INF/myschema.schemas";

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

private final ClassLoader classLoader;

private final String schemaMappingsLocation;

/** Stores the mapping of schema URL -> local schema path */
private volatile Map<String, String> schemaMappings;


/**
* Loads the schema URL -> schema file location mappings using the default
* mapping file pattern "META-INF/spring.schemas".
* @param classLoader the ClassLoader to use for loading
* (can be <code>null</code>) to use the default ClassLoader)
* @see PropertiesLoaderUtils#loadAllProperties(String, ClassLoader)
*/
public MyPluggableSchemaResolver(ClassLoader classLoader) {
this.classLoader = classLoader;
this.schemaMappingsLocation = DEFAULT_SCHEMA_MAPPINGS_LOCATION;
}

/**
* Loads the schema URL -> schema file location mappings using the given
* mapping file pattern.
* @param classLoader the ClassLoader to use for loading
* (can be <code>null</code>) to use the default ClassLoader)
* @param schemaMappingsLocation the location of the file that defines schema mappings
* (must not be empty)
* @see PropertiesLoaderUtils#loadAllProperties(String, ClassLoader)
*/
public MyPluggableSchemaResolver(ClassLoader classLoader, String schemaMappingsLocation) {
Assert.hasText(schemaMappingsLocation, "'schemaMappingsLocation' must not be empty");
this.classLoader = classLoader;
this.schemaMappingsLocation = schemaMappingsLocation;
}

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) {
String resourceLocation = getSchemaMappings().get(systemId);
if (resourceLocation != null) {
Resource resource = new ClassPathResource(resourceLocation, this.classLoader);
try {
InputSource source = new InputSource(resource.getInputStream());
source.setPublicId(publicId);
source.setSystemId(systemId);
if (logger.isDebugEnabled()) {
logger.debug("Found XML schema [" + systemId + "] in classpath: " + resourceLocation);
}
return source;
}
catch (FileNotFoundException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Couldn't find XML schema [" + systemId + "]: " + resource, ex);
}
}
}
}
return null;
}

/**
* Load the specified schema mappings lazily.
*/
private Map<String, String> getSchemaMappings() {
if (this.schemaMappings == null) {
synchronized (this) {
if (this.schemaMappings == null) {
if (logger.isDebugEnabled()) {
logger.debug("Loading schema mappings from [" + this.schemaMappingsLocation + "]");
}
try {
Properties mappings =
PropertiesLoaderUtils.loadAllProperties(this.schemaMappingsLocation, this.classLoader);
if (logger.isDebugEnabled()) {
logger.debug("Loaded schema mappings: " + mappings);
}
Map<String, String> schemaMappings = new ConcurrentHashMap<String, String>();
CollectionUtils.mergePropertiesIntoMap(mappings, schemaMappings);
this.schemaMappings = schemaMappings;
}
catch (IOException ex) {
throw new IllegalStateException(
"Unable to load schema mappings from location [" + this.schemaMappingsLocation + "]", ex);
}
}
}
}
return this.schemaMappings;
}


@Override
public String toString() {
return "EntityResolver using mappings " + getSchemaMappings();
}

}



META-INF/myschema.schemas

http\://www.ycl.com/schema/schema.xsd=org/frame/base/xml/jdk/schema.xsd


myschema.schemas

<?xml version="1.0" encoding="utf-8"?>
<xsd:schema elementFormDefault="qualified" attributeFormDefault="unqualified"
xmlns="http://www.ycl.com/schema/schema"
targetNamespace="http://www.ycl.com/schema/schema"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="contact">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="item" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="uic">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:minLength value="1" />
<xsd:maxLength value="250" />
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="fullName">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:minLength value="1" />
<xsd:maxLength value="250" />
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="width" type="xsd:string"></xsd:attribute>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值