Ignore DTD specification in scala
Asked Answered
S

3

18

I'd like to occasionally ignore the dtd specification while parsing an xml file using Scala. I know that this can be done pretty easily with the java interface by doing

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

However, I'm not sure of how to do this easily with Scala's xml library. If possible i'd like to continue using the scala xml library as it's significantly better.

Thanks in advance!

Stunk answered 3/7, 2012 at 16:44 Comment(0)
A
13

This works for me, but it depends on the implementation of the XML parser.

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

See also this question, which is really your question but worded in a hostile way.

Acknowledge answered 3/7, 2012 at 17:39 Comment(2)
I like this solution! And wow, that was a really hostile question.Stunk
Nice approach, although I found this didn't work for me, since it fails when it finds a DTD, instead of just ignoring it (could be implementation-dependent, as you note). I found that this did the trick though: f.setValidating(false); f.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);Hairbreadth
L
4

The first answer doesn't work when we have incorrect DOCTYPE in xml file. My solution is:

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()
  }
}
Lockup answered 24/10, 2015 at 22:7 Comment(1)
Thanks. This is the answer that fixed my particular version of this issue. The accepted on gives me SAXParseExceptions with DOCTYPE is disallowed when the feature "http://apache.org/xml/features/disallow-doctype-decl" set to true. My guess is that the XML that the poster was working with didn't have DOCTYPE declarations. Mine had them, but the DTD was not provided/wasn't in the right place/wasn't needed.Frida
S
1

First, I'm not an XML expert. So this is just some guessing...

val f = javax.xml.parsers.SAXParserFactory.newInstance()
f.setValidating(false)
val p = f.newSAXParser()
val doc = xml.XML.withSAXParser(p).load(url)
Spleenful answered 3/7, 2012 at 17:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.