2009-07-26 6 views
10

Je souhaite lire un fichier XML contenant une déclaration de schéma.Comment lire du XML bien formé en Java, mais ignorer le schéma?

Et c'est tout ce que je veux faire, lisez-le. Je m'en fous si c'est valide, mais je veux qu'il soit bien formé.

Le problème est que le lecteur essaie de lire le fichier de schéma et échoue.

Je ne veux même pas essayer.

J'ai essayé de désactiver la validation, mais il persiste à essayer de lire le fichier de schéma.

Idéalement, je voudrais le faire avec un stock Java 5 JDK.

Voici ce que j'ai jusqu'à présent, très simple:

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
    dbf.setValidating(false); 
    DocumentBuilder db = dbf.newDocumentBuilder(); 
    Document doc = db.parse(file); 

et est ici l'exception je reviens:

java.lang.RuntimeException: java.io.IOException: Server returned HTTP response code: 503 for URL: http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd 

Oui, cela arrive à être un schéma XHTML, mais ce n 't un problème "XHTML", c'est un problème XML. Juste en faisant remarquer que les gens ne sont pas distraits. Et, dans ce cas, le W3C dit en gros «ne demandez pas cette chose, c'est une idée idiote», et je suis d'accord. Mais, encore une fois, c'est un détail de la question, pas la racine de celui-ci. Je ne veux pas le demander du tout.

+0

Cela semble être lié à: http://stackoverflow.com/questions/155101/make-documentbuilder-parse-ignore-dtd-references –

Répondre

13

La référence ne concerne pas schéma, mais pour une DTD .

Les fichiers DTD peuvent contenir plus que des règles structurelles. Ils peuvent également contenir des références d'entité. Les parseurs XML sont obligés de charger et d'analyser les références DTD, car elles peuvent contenir des références d'entité pouvant affecter la façon dont le document est analysé et le contenu du fichier (vous pouvez avoir une référence d'entité pour les caractères ou même des phrases entières).

Si vous voulez éviter de charger et d'analyser la DTD référencée, you can provide your own EntityResolver et de tester la DTD référencée et de décider si charger une copie locale du fichier DTD ou simplement retourner null.

Exemple de code

de la réponse référencée sur EntityResolvers personnalisés:

builder.setEntityResolver(new EntityResolver() { 
     @Override 
     public InputSource resolveEntity(String publicId, String systemId) 
       throws SAXException, IOException { 
      if (systemId.contains("foo.dtd")) { 
       return new InputSource(new StringReader("")); 
      } else { 
       return null; 
      } 
     } 
    }); 
+0

Je pensais que c'est ce que je devais faire, j'ai simplement fait un EntityResolver "vide" qui retourne toujours le InputSource vide pour tout. Cela semblait faire l'affaire. –

+0

J'ai fait face au même problème et j'ai appliqué cette solution. Il a résolu l'IOException. Mon inquiétude est que le DOCTYPE se perd avec le reverbeur d'entité vide. Je souhaite que ce DOCTYPE soit conservé et non supprimé de l'entrée. C'est possible. – Rachel

0

Je ne l'ai pas testé, mais vous pouvez essayer d'appeler setSchema dans la fabrique en passant null.

à savoir

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
dbf.setValidating(false); 
dbf.setSchema(null); 
DocumentBuilder db = dbf.newDocumentBuilder(); 
Document doc = db.parse(file); 

Mise à jour: En regardant DocumentBuilderImpl il semble que cela pourrait fonctionner, du constructeur, il vérifiera la grammaire de l'usine avant de vérifier le schéma.

De DocumentBuilderFactoryImpl:

public void setSchema(Schema grammar) { 
    this.grammar = grammar; 
} 

De constructeur DocumentBuilderImpl:

... 
this.grammar = dbf.getSchema(); 
if (grammar != null) { 
    XMLParserConfiguration config = domParser.getXMLParserConfiguration(); 
    XMLComponent validatorComponent = null; 
    /** For Xerces grammars, use built-in schema validator. **/ 
    ... 
} 
+0

Désolé, cela ne semble pas fonctionner. – jpatokal

1

La question ne fait pas partie de la validation ici.Indépendamment des paramètres de validation, l'analyseur tente toujours de résoudre les références de votre document, telles que les entités, les DTD et (parfois) les schémas. Ce n'est que plus tard qu'il décide de valider en les utilisant (ou non). Vous devez brancher un résolveur d'entité pour "intercepter" ces tentatives de dé-référencement.

Découvrez Apache XML Resolver pour un moyen facile (ish) de le faire.

Questions connexes