package de.superx.bin; /* * Copyright 1999-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * $Id: Validate.java,v 1.5 2004/02/17 19:11:45 minchau Exp $ * * Erweitert für SuperX von Daniel Quathamer * 16.11.2006 */ import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FilenameFilter; import java.io.IOException; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import org.xml.sax.XMLReader; import org.xml.sax.ext.LexicalHandler; import org.xml.sax.helpers.DefaultHandler; /* Use JAXP SAXParser to parse 1 .xml file or all the .xml files in a directory. * Takes 1 or 2 command-line arguments: * Argument 1 (required) is a file name or directory name. * Argument 2 (optional) is a log file name. If ommitted, messages are written to screen. */ public class SxValidate { static int numXMLFiles = 0; static int numValidFiles = 0; static int numInvalidFiles = 0; static int numFilesMissingDoctype = 0; static int numMalformedFiles = 0; static boolean useSchema = false; static StringBuffer buff = new StringBuffer(); public static void main(String[] args) throws FileNotFoundException, IOException, ParserConfigurationException, SAXException { if (args.length == 0 || args.length > 2) { System.out.println("\nGeben Sie 'sx_validate.x -help' für Information über SxValidate"); System.exit(1); } if (args[0].toLowerCase().equals("-help")) { String sep = "\n====================================================\n"; String a = "sx_validate [SCHEMA] \nValidate nutzt Xerces um einen einzelnen XML-File zu validieren bzw. die xml Files in dem Verzeichnis das Sie spezifizieren. Der Parser validiert jedes Dokument (Konformität zum DOCTYPE oder XMLSchema).\n"; String b = "Jede xml Datei sollte eine DOCTYPE declaration oder einen XMLSchema-Verweis enthalten.\n\n"; String c = "SxValidate nimmt 1 oder 2 Argumente:\n"; String d = " Argument 1 spezifiziert das Verzeichnis oder die Datei.\n"; String e = " Argument 2 (einfach 'SCHEMA') spezifiziert, ob nach XML-Schema validiert werden soll.\n"; System.out.println(sep+a+b+c+d+e+sep); return; } try { SxValidate v = new SxValidate(); v.validate(args); System.exit(0); } catch (Exception e) { e.printStackTrace(); System.exit(1); } } void validate(String[] args) throws Exception { File dir = new File(args[0]); // User may include a 2nd argument for the validation method useSchema = false; if(args.length == 2 && args[1].equalsIgnoreCase("SCHEMA")) useSchema=true; if (dir.isFile()) // Just checking one file. { parse(null,args[0],useSchema); } else if (dir.isDirectory()) // Checking the contents of a directory. { // Only interested in .xml files. XMLFileFilter filter = new XMLFileFilter(); String [] files = dir.list(filter); for (int i = 0; i 1) buff.append("Parsed " + numXMLFiles + " .xml files in " + args[0] + ".\n"); if (numValidFiles > 1) buff.append( numValidFiles + " files are valid.\n"); else if (numValidFiles == 1) buff.append( numValidFiles + " file is valid.\n"); if (numInvalidFiles > 1) buff.append(numInvalidFiles + " files are not valid.\n"); else if (numInvalidFiles == 1) buff.append( numInvalidFiles + " file is not valid.\n"); if (numMalformedFiles > 1) buff.append(numMalformedFiles + " files are not well-formed.\n"); else if (numMalformedFiles == 1) buff.append( numMalformedFiles + " file is not well-formed.\n"); if (numFilesMissingDoctype > 1) buff.append(numFilesMissingDoctype + " files do not contain a DOCTYPE declaration.\n"); else if (numFilesMissingDoctype == 1) buff.append(numFilesMissingDoctype + " file does not contain a DOCTYPE declaration.\n"); System.out.print(buff.toString()); } // Parse each XML file. void parse(String dir, String filename,boolean useSchema) throws Exception { try { File f = new File(dir, filename); StringBuffer errorBuff = new StringBuffer(); InputSource input = new InputSource(new FileInputStream(f)); // Set systemID so parser can find the dtd with a relative URL in the source document. input.setSystemId(f.toString()); SAXParserFactory spfact = SAXParserFactory.newInstance(); spfact.setValidating(true); spfact.setNamespaceAware(true); SAXParser parser = spfact.newSAXParser(); XMLReader reader = parser.getXMLReader(); //Instantiate inner-class error and lexical handler. Handler handler = new Handler(filename, errorBuff); reader.setProperty("http://xml.org/sax/properties/lexical-handler", handler); if(useSchema) { parser.setProperty( "http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema"); buff.append("Nutze XML-Schema Validierung\n"); } parser.parse(input, handler); if (handler.containsDTD && !handler.errorOrWarning) // valid { buff.append("VALID " + filename +"\n"); numValidFiles++; } else if (handler.containsDTD) // not valid { buff.append ("NOT VALID " + filename + "\n"); buff.append(errorBuff.toString()); numInvalidFiles++; } else // no DOCTYPE to use for validation { if(handler.errorOrWarning) { buff.append("Datei " + filename +" wurde validiert:\n"+errorBuff.toString()); numInvalidFiles++; } else { buff.append("Datei " + filename +" wurde validiert:\n"+errorBuff.toString()); numValidFiles++; } } } catch (Exception e) // Serious problem! { buff.append("NOT WELL-FORMED " + filename + ". " + e.getMessage() + "\n"); numMalformedFiles++; throw new Exception(e); } finally { numXMLFiles++; } } // Inner classes // Only interested in parsing .xml files. class XMLFileFilter implements FilenameFilter { public boolean accept(File dir, String fileName) { return fileName.toLowerCase().endsWith(".xml") && new File(dir.toString(),fileName).isFile(); } } // Catch any errors or warnings, and verify presence of doctype statement. class Handler extends DefaultHandler implements LexicalHandler { boolean errorOrWarning; boolean containsDTD; String sourceFile; StringBuffer errorBuff; Handler(String sourceFile, StringBuffer errorBuff) { super(); this.sourceFile = sourceFile; this.errorBuff = errorBuff; errorOrWarning = false; containsDTD = false; } public void error(SAXParseException exc) { errorBuff.append(sourceFile + " Error: " + exc.getMessage()+ "\n"); errorOrWarning = true; } public void warning(SAXParseException exc) { errorBuff.append(sourceFile + " Warning:" + exc.getMessage()+ "\n"); errorOrWarning = true; } // LexicalHandler methods; all no-op except startDTD(). // Set containsDTD to true when startDTD event occurs. public void startDTD (String name, String publicId, String systemId) throws SAXException { containsDTD = true; } public void endDTD () throws SAXException {} public void startEntity (String name) throws SAXException {} public void endEntity (String name) throws SAXException {} public void startCDATA () throws SAXException {} public void endCDATA () throws SAXException {} public void comment (char ch[], int start, int length) throws SAXException {} } }