2010-06-07 4 views
9

Je veux valider un fichier XML par rapport à un schéma XSD. L'élément racine des fichiers XML n'a pas d'espace de noms ou de détails xsi. Il n'a aucun attribut si juste <root>.Java validation xsd de xml sans espace de noms

J'ai essayé le code suivant de http://www.ibm.com/developerworks/xml/library/x-javaxmlvalidapi.html sans chance que je reçois 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); 

Le xml valide bien avec les en-têtes d'espace de noms inclus etc (ajouté par XMLSpy), mais j'aurais pensé que le xml namespace pourrait être déclaré sans avoir à modifier manuellement le fichier source?

Modifier et Solution:

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

Répondre

2

Vous avez deux préoccupations distinctes que vous devez prendre soin de:

  1. Déclarant l'espace de noms que votre document utilise.
  2. En mettant un xsi:schemaLocation attribut dans le fichier pour donner un indice (!) où le schéma est.

Vous pouvez ignorer la deuxième partie en toute sécurité, car l'emplacement est vraiment un indice. Vous ne pouvez pas ignorer la première partie. L'espace de noms déclaré dans le fichier XML est comparé au schéma. Important, ceci:

<xml> ... </xml> 

est pas le même que cela:

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

Alors vous devez déclarer votre espace de noms dans le document XML, sinon il ne correspondra pas à votre schéma et vous obtenir cette erreur.

+1

Le document xml est créé par un tiers, ils n'ont peut-être pas ajouté l'espace de noms correct, y at-il un moyen java d'ajouter facilement cet espace de noms à l'élément xml racine avant de valider? –

+2

Il y a deux choses que vous pouvez faire à ce sujet: 1. insérez-le en utilisant la manipulation de chaînes si vous savez ce que vous faites et le format est plutôt statique ou mieux 2. créez un filtre SAX qui change l'espace de noms (voir http: // www.saxproject.org/filters.html), et passez le filtre au validateur. Je n'ai pas essayé avec un objet Validator, mais j'espère que cela fonctionnera. – xcut

+1

Merci xcut. J'ai fait des recherches sur les filtres et cela fonctionne parfaitement. Pour les autres voir la solution dans mon post original ci-dessus. –