2009-11-13 17 views
6

Sto tentando di analizzare uno schema XML piuttosto complicato in un oggetto Schema in Java in modo da poter eseguire alcune convalide sui messaggi XML.Parsing Schema in Java Con le importazioni e include?

Il mio codice è simile a questo:

SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); 
Schema schema = factory.newSchema(new StreamSource(new File("schema/schema.xsd"))); 

mio schema ha un bel paio di importazioni:

<?xml version="1.0" encoding="UTF-8"?> 
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="base_1"> 
    <xs:import namespace="base_1" schemaLocation="common/MessageBase.xsd"/> 
</xs:schema>

... ecc. Quando tento di caricare lo schema, ottengo molti errori. Sulla base di un'altra domanda relativa a questo, sembra che ho bisogno di specificare un risolutore di risorse, ma non è qualcosa che dovrebbe essere gestito di default?

In tal caso, esiste una directory specifica in cui è necessario mettere lo schema in relazione a dove eseguo l'applicazione che sto scrivendo o relativa al file dello schema di base?

Infine, quando carico lo schema con XMLSpy o simili, funziona correttamente e posso convalidare le istanze XML senza problemi.

risposta

8

Penso che l'uso di StreamSource, senza specificare la posizione di base, sia la fonte del problema.

Il parser non ha modo di sapere dove si trova lo schema principale, quindi non può risolvere common/MessageBase.xml.

Utilizzare il costruttore di due argomenti e passare un SystemID che è il nome del percorso da cui si sta iniziando.

Vedere javadoc per StreamSource.

+0

provato questo e ancora ottenere il seguente errore: src-determinazione: Impossibile risolvere il nome 'di base: StatusWithError_optional' a un (n) componente 'gruppo di attributi'. – magneticMonster

+0

Questo è un altro problema. Suggerisce che il tuo schema non è completo e autonomo. Hai un gruppo di attributi denominato StatusWithError_optional? È nel giusto spazio dei nomi? – bmargulies

+0

Sì, è definito in un file separato allo stesso livello del file di schema di base. Stesso spazio dei nomi. Il systemID deve essere il percorso del file .xsd root o della directory root per lo schema? Che ne dici dell'altro argomento del costruttore di 2-arg? – magneticMonster

2

Al fine di risolvere i XSD importati è necessario associare la fabbrica schema con un resolver risorsa:

SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); 
factory.setResourceResolver(new MyResourceResolver()); 
Schema schema = factory.newSchema(new StreamSource(new File("schema/schema.xsd"))); 

Per ulteriori dettagli si può guardare a questo answer.

7

Non è necessario un resolver di risorse se si utilizza un URL anziché un StreamSource.

URL schemaURL = Thread.currentThread().getContextClassLoader().getResource(schemaFileName); 
SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); 
Schema schema = schemaFactory.newSchema(schemaURL); 
+0

+1 per la soluzione molto più semplice! Ha funzionato per me – AKeefe

+0

è semplice in quanto non richiede il resolver. – ulab

+2

L'ho già fatto usando un URL, ma ancora non ho risolto le risorse correttamente per me quando aveva a che fare con le importazioni. Ho usato un ResourceResolver, ed è stato risolto però. Perché funziona per te, e non per me rimane la domanda. forse ha a che fare con la struttura del progetto. I percorsi nei miei file xsd sono relativi al mio classpath java, la mia ipotesi migliore è che la tua possa essere relativa alla tua cartella di lavoro. – bvdb