2010-06-07 23 views
9

Voglio convalidare un file XML su uno schema XSD. L'elemento root dei file XML non ha spazio dei nomi o dettagli xsi. Non ha attributi quindi solo <root>.Convalida xsd Java di xml senza namespace

Ho provato il seguente codice da http://www.ibm.com/developerworks/xml/library/x-javaxmlvalidapi.html senza fortuna ricevo cvc-elt.1: Cannot find the declaration of element 'root'

SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema"); 

File schemaFile = new File("schema.xsd"); 

Schema xsdScheme = factory.newSchema(schemaFile); 

Validator validator = xsdScheme.newValidator(); 

Source source = new StreamSource(xmlfile); 

validator.validate(source); 

il codice XML valida fino con le intestazioni namespace inclusi etc (aggiunto via XMLSpy), ma avrei pensato che il xml spazio dei nomi potrebbe essere dichiarato senza dover modificare manualmente il file sorgente?

Edit e soluzione:

public static void validateAgainstXSD(File file) { 

    try { 
     SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema"); 

     File schemaFile = new File("path/to/xsd"); 

     Schema xsdScheme = factory.newSchema(schemaFile); 

     Validator validator = xsdScheme.newValidator(); 

     SAXSource source = new SAXSource(
       new NamespaceFilter(XMLReaderFactory.createXMLReader()), 
       new InputSource(new FileInputStream(file))); 

     validator.validate(source,null); 

    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

} 

protected static class NamespaceFilter extends XMLFilterImpl { 

    String requiredNamespace = "namespace"; 

    public NamespaceFilter(XMLReader parent) { 
     super(parent); 
    } 

    @Override 
    public void startElement(String arg0, String arg1, String arg2, Attributes arg3) throws SAXException { 
     if(!arg0.equals(requiredNamespace)) 
      arg0 = requiredNamespace; 
     super.startElement(arg0, arg1, arg2, arg3); 
    }  
} 

risposta

2

Hai due preoccupazioni separati è necessario prendersi cura di:

  1. Dichiarando lo spazio dei nomi che il documento utilizza.
  2. Inserire un attributo xsi:schemaLocation nel file per fornire un suggerimento (!) dove si trova lo schema.

È possibile saltare in sicurezza la seconda parte, poiché la posizione è solo un suggerimento. Non puoi saltare la prima parte. Lo spazio dei nomi dichiarato nel file XML viene confrontato con lo schema. Importante, in questo modo:

<xml> ... </xml> 

è non è la stessa come questo:

<xml xmlns="urn:foo"> ... </xml> 

Quindi è necessario dichiarare lo spazio dei nomi nel documento XML, altrimenti non sarà conforme allo schema e vi ottieni questo errore

+1

Il documento xml viene creato da una terza parte, potrebbe non aver aggiunto lo spazio dei nomi corretto, esiste un modo in Java per aggiungere facilmente questo spazio dei nomi all'elemento xml di root prima di convalidare? –

+2

Ci sono due cose che puoi fare al riguardo: 1. inseriscilo usando la manipolazione delle stringhe se sai cosa stai facendo e il formato è abbastanza statico o migliore 2. crea un filtro SAX che cambia lo spazio dei nomi (vedi http: // www.saxproject.org/filters.html) e passare il filtro al Validator. Non l'ho provato con un oggetto Validator, ma spero che funzionerà. – xcut

+1

Grazie xcut. Ho studiato i filtri e funziona in modo esagerato. Per gli altri vedere la soluzione nel mio post originale sopra. –