0

I am a newbie to java and eclipse. I was trying to load an XML file using properties.loadFromXML() and tried to read properties's names. but I ended with getting SAXparseException saying "Element type must be declared", even though I have defined DTD for my XML file. Could someone help me? this is my XML file

<?xml version="1.0"?>
<!DOCTYPE test [
<!ELEMENT test (name, price, hsn)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT price (#PCDATA)>
<!ELEMENT hsn (#PCDATA)>
]>
<test>
    <name>groundnut</name>
    <price>5.00</price>
    <hsn>ABCDE</hsn>
</test>

this is my java code: import java.util.Properties; import java.util.Set;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import java.io.File;
import java.io.IOException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import java.io.File;

import java.io.*;


public class test 
{
    public static void main(String args[]) throws Exception
    {
        Properties p = new Properties();
        InputStream is = new FileInputStream("resources/test.XML");
        p.loadFromXML(is);
        System.out.print(p.stringPropertyNames());

    }
}

this is the output I got:

Exception in thread "main" java.util.InvalidPropertiesFormatException: jdk.internal.org.xml.sax.SAXParseException; Element type "test" must be declared.
at java.base/jdk.internal.util.xml.PropertiesDefaultHandler.load(PropertiesDefaultHandler.java:85)
at java.base/java.util.Properties.loadFromXML(Properties.java:956)
at test.main(test.java:28)

Caused by: jdk.internal.org.xml.sax.SAXParseException; Element type "test" must be declared. at java.base/jdk.internal.util.xml.PropertiesDefaultHandler.startElement(PropertiesDefaultHandler.java:169) at java.base/jdk.internal.util.xml.impl.ParserSAX.parse(ParserSAX.java:470) at java.base/jdk.internal.util.xml.impl.ParserSAX.parse(ParserSAX.java:411) at java.base/jdk.internal.util.xml.impl.ParserSAX.parse(ParserSAX.java:374) at java.base/jdk.internal.util.xml.impl.SAXParserImpl.parse(SAXParserImpl.java:97) at java.base/jdk.internal.util.xml.PropertiesDefaultHandler.load(PropertiesDefaultHandler.java:83) ... 2 more

1 Answers1

1

Importing XML using Properties.loadFromXML() does not support the use of custom DTDs. It only supports the DTD documented in the Properties Javadoc.

It's not clear why you think you can use an alternative DTD to read in properties like this.

You will instead have to modify your XML document to match the Properties DTD:

<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
    <entry key="name">groundnut</entry>
    <entry key="price">5.00</entry>
    <entry key="hsn">ABCDE</entry>
</properties>
Luke Woodward
  • 63,336
  • 16
  • 89
  • 104
  • Thanks luke woodward! As you asked, i going to have multiple items each of which is going to have corresponding name,price and hsn. I'm still not clear how am i going to alter DTD for my need. Can i have multiple entry tag as parent to children(name, price, hsn)? – shuvethram ragupathy Apr 26 '20 at 14:23
  • In that case it looks like using `Properties` is the wrong thing to do. A `Properties` class is for a string-to-string mapping but I don't see how this would fit with your data. You will have to parse your XML in a different way. – Luke Woodward Apr 26 '20 at 14:54
  • Thanks luke! I'm using DocumentFactoryBuilder class now hoping its the right way – shuvethram ragupathy Apr 27 '20 at 15:23
  • What to do when http://java.sun.com/dtd/properties.dtd is blocked? – Gentleman Apr 25 '23 at 11:13
  • @Gentleman what do you mean? From the link in my answer: "Note that the system URI (http://java.sun.com/dtd/properties.dtd) is not accessed when exporting or importing properties; it merely serves as a string to uniquely identify the DTD, which is:...". If you are on some kind of corporate network which blocks access to that URL, then that shouldn't make a difference: Java should still be able to load a properties file. If however you are getting an error which suggests that a request is being made to that URL, then please ask a separate question. – Luke Woodward Apr 25 '23 at 22:21