Java利用多個XSD Validation驗證XML

網路已有神人寫出利用多個XSD檔案,Validation驗證XML內容。
所以原來真正的重點是要繼承 LSResourceResolver。
參考:
http://stackoverflow.com/questions/2342808/problem-validating-an-xml-file-using-java-with-an-xsd-having-an-include
http://terrencexu.iteye.com/blog/703749

class SchemaResourceResolver implements LSResourceResolver {
	public LSInput resolveResource(String type, String namespaceURI, String publicId, String systemId, String baseURI) {
		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;
	}

	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;
		}
		
	}

}

執行程式

public final class XMLParser {

	private static final Logger log = Logger.getLogger(XMLParser.class);
	public static void main(String [] args){
		try {
			InputStream xml = XMLParser.class.getResourceAsStream("/resource/demo1.xml");
			List<File> schemas = new ArrayList<File>();
			schemas.add( new File(XMLParser.class.getResource("/resource/CDA.xsd").toURI()) );
			if ( XMLParser.validateWithSingleSchema(new File(XMLParser.class.getResource("/resource/demo1.xml").toURI()), new File(XMLParser.class.getResource("/resource/CDAAll.xsd").toURI())) )
				log.info("Single Schema Pass");
			if ( XMLParser.validateWithMultiSchemas(xml, schemas) )
				log.info("Multi Schema Pass");
			xml.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (URISyntaxException e) {
			e.printStackTrace();
		}
	}
	
	public static boolean validateWithSingleSchema(File xml, File xsd) {
		boolean legal = false;
		
		try {
			SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
			Schema schema = sf.newSchema(xsd);
			Validator validator = schema.newValidator();
			validator.validate(new StreamSource(xml));
			legal = true;
		} catch (SAXParseException e) {
			legal = false;
			log.error("lineNumber: " + e.getLineNumber() + "; columnNumber: " + e.getColumnNumber() + "; " + e.getMessage());
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			log.error("File Read ERROR");
			e.printStackTrace();
		}
		
		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(SAXParseException e) {
        	legal = false;
        	log.error("lineNumber: " + e.getLineNumber() + "; columnNumber: " + e.getColumnNumber() + "; " + e.getMessage());
        } catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			log.error("File Read ERROR");
			e.printStackTrace();
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		}
		
		return legal;
	}

	private static Schema createSchema(List<File> schemas) throws ParserConfigurationException, SAXException, IOException {
		SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
		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);
	}
}
廣告

About fenjj

Perfect !!??...
本篇發表於 Uncategorized。將永久鏈結加入書籤。

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

您的留言將使用 WordPress.com 帳號。 登出 / 變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 / 變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 / 變更 )

Google+ photo

您的留言將使用 Google+ 帳號。 登出 / 變更 )

連結到 %s