2012-07-03 13 views
17

Mi piacerebbe occasionalmente ignorare le specifiche di dtd durante l'analisi di un file xml utilizzando Scala. So che questo può essere fatto abbastanza facilmente con l'interfaccia Java facendoIgnora le specifiche DTD in scala

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 

dbf.setValidating(false); 
dbf.setFeature("http://xml.org/sax/features/namespaces", false); 
dbf.setFeature("http://xml.org/sax/features/validation", false); 
dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false); 
dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); 

Tuttavia, non sono sicuro di come farlo facilmente con la libreria XML di Scala. Se possibile mi piacerebbe continuare ad usare la libreria scala xml in quanto è significativamente migliore.

Grazie in anticipo!

risposta

11

Questo funziona per me, ma dipende dall'implementazione del parser XML.

import scala.xml.Elem 
import scala.xml.factory.XMLLoader 
import javax.xml.parsers.SAXParser 
object MyXML extends XMLLoader[Elem] { 
    override def parser: SAXParser = { 
    val f = javax.xml.parsers.SAXParserFactory.newInstance() 
    f.setNamespaceAware(false) 
    f.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); 
    f.newSAXParser() 
    } 
} 

Vedi anche this question, che è davvero la tua domanda, ma formulata in modo ostile.

+0

Mi piace questa soluzione! E wow, questa era una domanda davvero ostile. – fozziethebeat

+6

Un buon approccio, anche se ho trovato che questo non ha funzionato per me, dal momento che fallisce quando trova una DTD, invece di ignorarla (potrebbe dipendere dall'implementazione, come si nota). Ho trovato che questo ha fatto il trucco però: 'f.setValidating (false); f.setFeature ("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); ' –

+0

@strangefeatures Grazie. quello ha aiutato. – Jus12

1

In primo luogo, non sono un esperto di XML. Quindi questa è solo una supposizione ...

val f = javax.xml.parsers.SAXParserFactory.newInstance() 
f.setValidating(false) 
val p = f.newSAXParser() 
val doc = xml.XML.withSAXParser(p).load(url) 
2

La prima risposta non funziona quando abbiamo DOCTYPE errato nel file xml. La mia soluzione è:

import scala.xml.Elem 
import scala.xml.factory.XMLLoader 
import javax.xml.parsers.SAXParser 
object XML extends XMLLoader[Elem] { 
    override def parser: SAXParser = { 
    val f = javax.xml.parsers.SAXParserFactory.newInstance() 
    f.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false); 
    f.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); 
    f.newSAXParser() 
    } 
} 
+0

Grazie. Questa è la risposta che ha risolto la mia particolare versione di questo problema. L'accettato su mi dà SAXParseExceptions con 'DOCTYPE non è consentito quando la funzione" http://apache.org/xml/features/disallow-doctype-decl "è impostata su true'. La mia ipotesi è che l'XML con cui il poster stava lavorando non avesse dichiarazioni DOCTYPE. Il mio li aveva, ma il DTD non è stato fornito/non era nel posto giusto/non era necessario. – AndrewO