使用xsd验证xml

之前写的文章利用到了dom4j,而且是单个的xsd验证。但是项目实际需求是xsd中引用了其他的xsd。即有验证结构的,也有验证内容的。

以下是多个xsd联合验证xml的代码,没有用到dom4j,使用的是java自己的API。

代码是同事的朋友给的,不知出处,如果侵犯到了原作者的权益,请联系我。

Anyway,感谢写出代码的同行,帮我解决了问题。


代码写了三个类文件。

SchemaResourceResolver.java

import  java.io.File;  
import  java.io.FileInputStream;  
import  java.io.FileNotFoundException;  
import  java.io.InputStream;  
import  java.io.Reader;  
import  java.net.URI;  
import  java.net.URISyntaxException;  
  
import  org.apache.log4j.Logger;  
import  org.w3c.dom.ls.LSInput;  
import  org.w3c.dom.ls.LSResourceResolver;  
  
/**  
 *   
 * Implement LSResourceResolver to customize resource resolution when parsing schemas.  
 * <p>  
 * SchemaFactory uses a LSResourceResolver when it needs to locate external resources   
 * while parsing schemas, although exactly what constitutes "locating external resources"   
 * is up to each schema language.   
 * </p>  
 * <p>  
 * For example, for W3C XML Schema, this includes files <include>d or <import>ed,   
 * and DTD referenced from schema files, etc.  
 *</p>  
 *  
 */   
class  SchemaResourceResolver  implements  LSResourceResolver {  
  
    private   static   final  Logger log = Logger.getLogger(SchemaResourceResolver. class );  
      
    /**  
     *   
     * Allow the application to resolve external resources.   
     *   
     * <p>  
     * The LSParser will call this method before opening any external resource, including   
     * the external DTD subset, external entities referenced within the DTD, and external   
     * entities referenced within the document element (however, the top-level document   
     * entity is not passed to this method). The application may then request that the   
     * LSParser resolve the external resource itself, that it use an alternative URI,   
     * or that it use an entirely different input source.   
     * </p>  
     *   
     * <p>  
     * Application writers can use this method to redirect external system identifiers to   
     * secure and/or local URI, to look up public identifiers in a catalogue, or to read   
     * an entity from a database or other input source (including, for example, a dialog box).  
     * </p>  
     */   
    public  LSInput resolveResource(String type, String namespaceURI, String publicId, String systemId, String baseURI) {  
        log.info("/n>> Resolving "  +  "/n"   
                          + "TYPE: "  + type +  "/n"   
                          + "NAMESPACE_URI: "  + namespaceURI +  "/n"    
                          + "PUBLIC_ID: "  + publicId +  "/n"   
                          + "SYSTEM_ID: "  + systemId +  "/n"   
                          + "BASE_URI: "  + baseURI +  "/n" );  
          
        String schemaLocation = baseURI.substring(0 , baseURI.lastIndexOf( "/" ) +  1 );  
          
        if (systemId.indexOf( "http://" ) <  0 ) {  
            systemId = schemaLocation + systemId;  
        }  
          
        LSInput lsInput = new  LSInputImpl();  
          
        URI uri = null ;  
        try  {  
            uri = new  URI(systemId);  
        } catch  (URISyntaxException e) {  
            e.printStackTrace();  
        }  
          
        File file = new  File(uri);  
        FileInputStream is = null ;  
        try  {  
            is = new  FileInputStream(file);  
        } catch  (FileNotFoundException e) {  
            e.printStackTrace();  
        }  
          
        lsInput.setSystemId(systemId);  
        lsInput.setByteStream(is);  
          
        return  lsInput;  
    }  
      
    /**  
     *   
     * Represents an input source for data  
     *  
     */   
    class  LSInputImpl  implements  LSInput {  
  
        private  String publicId;  
        private  String systemId;  
        private  String baseURI;  
        private  InputStream byteStream;  
        private  Reader charStream;  
        private  String stringData;  
        private  String encoding;  
        private   boolean  certifiedText;  
          
        public  LSInputImpl() {}  
          
        public  LSInputImpl(String publicId, String systemId, InputStream byteStream) {  
            this .publicId = publicId;  
            this .systemId = systemId;  
            this .byteStream = byteStream;  
        }  
          
        public  String getBaseURI() {  
            return  baseURI;  
        }  
  
        public  InputStream getByteStream() {  
            return  byteStream;  
        }  
  
        public   boolean  getCertifiedText() {  
            return  certifiedText;  
        }  
  
        public  Reader getCharacterStream() {  
            return  charStream;  
        }  
  
        public  String getEncoding() {  
            return  encoding;  
        }  
  
        public  String getPublicId() {  
            return  publicId;  
        }  
  
        public  String getStringData() {  
            return  stringData;  
        }  
  
        public  String getSystemId() {  
            return  systemId;  
        }  
  
        public   void  setBaseURI(String baseURI) {  
            this .baseURI = baseURI;  
        }  
  
        public   void  setByteStream(InputStream byteStream) {  
            this .byteStream = byteStream;  
        }  
  
        public   void  setCertifiedText( boolean  certifiedText) {  
            this .certifiedText = certifiedText;  
        }  
  
        public   void  setCharacterStream(Reader characterStream) {  
            this .charStream = characterStream;  
        }  
  
        public   void  setEncoding(String encoding) {  
            this .encoding = encoding;  
        }  
  
        public   void  setPublicId(String publicId) {  
            this .publicId = publicId;  
        }  
  
        public   void  setStringData(String stringData) {  
            this .stringData = stringData;  
        }  
  
        public   void  setSystemId(String systemId) {  
            this .systemId = systemId;  
        }  
          
    }  
  
}   



XMLParser.java

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;

import org.apache.log4j.Logger;
import org.xml.sax.SAXException;

public final class XMLParser {

	private static final Logger log = Logger.getLogger(XMLParser.class);

	private XMLParser() {
	}

	public static boolean validateWithSingleSchema(File xml, File xsd) {
		boolean legal = false;

		try {
			SchemaFactory sf = SchemaFactory
					.newInstance("http://www.w3.org/2001/XMLSchema");
			Schema schema = sf.newSchema(xsd);

			Validator validator = schema.newValidator();
			validator.validate(new StreamSource(xml));

			legal = true;
		} catch (Exception e) {
			legal = false;
			log.error(e.getMessage());
		}

		return legal;
	}

	public static boolean validateWithMultiSchemas(InputStream xml,
			List<File> schemas) {
		boolean legal = false;

		try {
			Schema schema = createSchema(schemas);

			Validator validator = schema.newValidator();
			
			validator.validate(new StreamSource(xml));
			
			legal = true;
		} catch (Exception e) {
			legal = false;
			log.error(e.getMessage());
		}

		return legal;
	}

	/**
	 * Create Schema object from the schemas file.
	 * 
	 * @param schemas
	 * @return
	 * @throws ParserConfigurationException
	 * @throws SAXException
	 * @throws IOException
	 */
	public static Schema createSchema(List<File> schemas)
			throws ParserConfigurationException, SAXException, IOException {
		SchemaFactory sf = SchemaFactory
				.newInstance("http://www.w3.org/2001/XMLSchema");
		SchemaResourceResolver resourceResolver = new SchemaResourceResolver();
		sf.setResourceResolver(resourceResolver);

		Source[] sources = new Source[schemas.size()];

		DocumentBuilderFactory docFactory = DocumentBuilderFactory
				.newInstance();
		docFactory.setValidating(false);
		docFactory.setNamespaceAware(true);
		DocumentBuilder docBuilder = docFactory.newDocumentBuilder();

		for (int i = 0; i < schemas.size(); i++) {
			org.w3c.dom.Document doc = docBuilder.parse(schemas.get(i));
			DOMSource stream = new DOMSource(doc, schemas.get(i)
					.getAbsolutePath());
			sources[i] = stream;
		}

		return sf.newSchema(sources);
	}

}


XSLTParser.java

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Templates;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

public class XSLTParser {

	public static void xslt(String inFilename, String outFilename,
			String xsltFilename) {
		try {
			// Create transformer factory
			TransformerFactory factory = TransformerFactory.newInstance();

			// Use the factory to create a template containing the xsl file
			Templates template = factory.newTemplates(new StreamSource(
					new FileInputStream(xsltFilename)));

			// Use the template to create a transformer
			Transformer xformer = template.newTransformer();

			// Prepare the input and output files
			Source source = new StreamSource(new FileInputStream(inFilename));
			Result result = new StreamResult(new FileOutputStream(outFilename));

			// Apply the xsl file to the source file and write the result to the
			// output file
			xformer.transform(source, result);
		} catch (FileNotFoundException e) {
			// File not found
		} catch (TransformerConfigurationException e) {
			// An error occurred in the XSL file
		} catch (TransformerException e) {
			// An error occurred while applying the XSL file
			// Get location of error in input file
		}
	}
}



测试方法:

public boolean testValidate() throws SAXException,
			FileNotFoundException {
		InputStream xml = new FileInputStream(new File("data.xml"));

		List<File> schemas = new ArrayList<File>();
		schemas.add(new File("DeclarationTypeCode.xsd"));
		schemas.add(new File("HeadDefine.xsd"));

		schemas.add(new File("DateTimeDefine.xsd"));
//		schemas.add(new File("DeclarationDefine.xsd"));
		schemas.add(new File("base.xsd"));
		return XMLParser.validateWithMultiSchemas(xml, schemas);
	}


说明:验证的XSD为base.xsd,

在base.xsd中import了HeadDefine.xsd和DeclarationDefine.xsd,

在HeadDefine.xsd中又import了DeclarationTypeCode.xsd

在DeclarationDefine.xsd中又import了DateTimeDefine.xsd


测试结果,此测试方法返回true则验证成功,返回false则验证失败。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值