Search code examples
javaxmlxml-parsingdtdnetbeans-8

XMLReader searches for DTD files relatively to main app instead of XML file


I'm trying to run some XML parsings using Netbeans as the IDE. My project is in F:\Project and my XML is in D:\XML\data.xml along with D:\XML\validation.dtd. The dtd file is referred in my XML as followed:

<!DOCTYPE softwarelist SYSTEM "validation.dtd">

But I don't understand why the XMLReader is searching for the dtd relatively to the project folder instead of the XML folder?

Here's the parsing code:

    try {
        SAXParserFactory spf = SAXParserFactory.newInstance();
        spf.setNamespaceAware(false);
        XMLReader xmlReader = spf.newSAXParser().getXMLReader();

        xmlReader.parse(new InputSource(Files.newInputStream(path)));
    } catch (ParserConfigurationException | SAXException | IOException ex) {
        Logger.getLogger(SoftwareListLoader.class.getName()).log(Level.SEVERE, null, ex);
    }

I get this error:

java.io.FileNotFoundException: F:\Project\softwarelist.dtd (Specified file not found)

Is there a way to tell the parser to find the dtd relatively to the XML document file?


Solution

  • Thanks to Google and O'Reilly, now I understand what's happening.

    The thing is I pass the XML file to the parser as a stream, which literally looses any references to the original file path. To fix this, there are 2 solutions:

    1/ set the original file path as the System ID of the XML document.

    InputSource source = new InputSource(Files.newInputStream(path));
    source.setSystemId(path.toString());
    xmlReader.parse(source);
    

    2/ do not go through streams.

    xmlReader.parse(new InputSource(path.toString()));
    

    Reference: http://docstore.mik.ua/orelly/xml/jxml/ch03_02.htm