Header javaperspective.com
JavaPerspective.com  >   Advanced Tutorials  >   3. XML processing with JDOM  >   3.13. Working with DTDs

3.13. Working with DTDs
Last updated: 2 January 2013.

This tutorial will show you how to use DTDs with the JDOM library.

The JDOM API allows you to declare an external or internal DTD when creating an XML document. A DTD is an instance of the class DocType. To declare a DTD, use the following constructor:

Document(Element rootElement, DocType docType)

Alternatively, you can call the method setDocType provided by the class Document after having created the document.

If you want to declare a public DTD, create a DocType object with the following constructor:

DocType(java.lang.String elementName, java.lang.String publicID, java.lang.String systemID)

Here is an example which uses the constructor Document(Element rootElement, DocType docType) to declare an external DTD:

import org.jdom2.DocType;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;


public final class JDOMDemo {


   
private void createXmlWithExternalDocType(){
         
try {
               
// Create the root element
               
Element rootElement = new Element("HOTEL");

               
// Create a new ROOM element
               
Element room = new Element("ROOM");

               
// Set up a new NUMBER element and add it to ROOM
               
Element number = new Element("NUMBER");
                number.addContent
("17");
                room.addContent
(number);

               
// Set up a CATEGORY element and add it to ROOM
               
Element category = new Element("CATEGORY");
                category.addContent
("STANDARD");
                room.addContent
(category);

               
// Set up a BED element and add it to ROOM
               
Element bed = new Element("BED");
                bed.addContent
("DOUBLE SIZE");
                room.addContent
(bed);

               
// Set up a FLOOR element and add it to ROOM
               
Element floor = new Element("FLOOR");
                floor.addContent
("5");
                room.addContent
(floor);

               
// Set up an AIR_CONDITIONING element and add it to ROOM
               
Element airConditioning = new Element("AIR_CONDITIONING");
                airConditioning.addContent
(new Element("TABLE_FANS").addContent("2"));
                room.addContent
(airConditioning);

               
// Add the newly created ROOM element to the root element
               
rootElement.addContent(room);

               
//############################################################################
                // Create the document with the root element and DocType instance
               
Document document = new Document(rootElement, new DocType("HOTEL", "hotel.dtd"));
               
//############################################################################

                // Output the JDOM document to the standard output
               
XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat());
                outputter.output
(document, System.out);
         
}
         
catch (Exception e) {
               
e.printStackTrace();
         
}
    }


   
public static void main(String[] args){
         
new JDOMDemo().createXmlWithExternalDocType();
   
}

}

Here is the output:

   <?xml version="1.0" encoding="UTF-8"?>
   <!DOCTYPE HOTEL SYSTEM "hotel.dtd">
   <HOTEL>
            <ROOM>
                     <NUMBER>17</NUMBER>
                     <CATEGORY>STANDARD</CATEGORY>
                     <BED>DOUBLE SIZE</BED>
                     <FLOOR>5</FLOOR>
                     <AIR_CONDITIONING>
                              <TABLE_FANS>2</TABLE_FANS>
                     </AIR_CONDITIONING>
            </ROOM>
   </HOTEL>

To declare an internal DTD, use the method setInternalSubset provided by the class DocType like this:

import org.jdom2.DocType;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;


public final class JDOMDemo {


   
private void createXmlWithInternalDocType(){
         
try {
               
// Create the root element
               
Element rootElement = new Element("HOTEL");

               
// Create a new ROOM element
               
Element room = new Element("ROOM");

               
// Set up a new NUMBER element and add it to ROOM
               
Element number = new Element("NUMBER");
                number.addContent
("17");
                room.addContent
(number);

               
// Set up a CATEGORY element and add it to ROOM
               
Element category = new Element("CATEGORY");
                category.addContent
("STANDARD");
                room.addContent
(category);

               
// Set up a BED element and add it to ROOM
               
Element bed = new Element("BED");
                bed.addContent
("DOUBLE SIZE");
                room.addContent
(bed);

               
// Set up a FLOOR element and add it to ROOM
               
Element floor = new Element("FLOOR");
                floor.addContent
("5");
                room.addContent
(floor);

               
// Set up an AIR_CONDITIONING element and add it to ROOM
               
Element airConditioning = new Element("AIR_CONDITIONING");
                airConditioning.addContent
(new Element("TABLE_FANS").addContent("2"));
                room.addContent
(airConditioning);

               
// Add the newly created ROOM element to the root element
               
rootElement.addContent(room);

               
//#############################################################################
                // Set up the dtd string
               
StringBuilder dtd = new StringBuilder()
               
.append("<!ELEMENT HOTEL (ROOM+)>\n")
               
.append("<!ELEMENT ROOM (NUMBER, CATEGORY, BED+, FLOOR, LIVING_ROOM*,
                                KITCHENETTE*, JACUZZI?, AIR_CONDITIONING)>\n"
)
               
.append("<!ELEMENT NUMBER (#PCDATA)>\n")
               
.append("<!ELEMENT CATEGORY (#PCDATA)>\n")
               
.append("<!ELEMENT BED (#PCDATA)>\n")
               
.append("<!ELEMENT FLOOR (#PCDATA)>\n")
               
.append("<!ELEMENT LIVING_ROOM (#PCDATA)>\n")
               
.append("<!ELEMENT KITCHENETTE (#PCDATA)>\n")
               
.append("<!ELEMENT JACUZZI (#PCDATA)>\n")
               
.append("<!ELEMENT AIR_CONDITIONING (TABLE_FANS | AIR_CONDITIONERS)>\n")
               
.append("<!ELEMENT TABLE_FANS (#PCDATA)>\n")
               
.append("<!ELEMENT AIR_CONDITIONERS (#PCDATA)>\n")
               
.append("<!ATTLIST HOTEL name CDATA #IMPLIED>\n")
               
.append("<!ATTLIST HOTEL starRating CDATA #IMPLIED>");

               
// Set up the DocType object
               
DocType docType = new DocType("HOTEL");
                docType.setInternalSubset
(dtd.toString());

               
// Create the document with the root element and internal dtd
               
Document document = new Document(rootElement, docType);
               
//#############################################################################

                // Output the JDOM document to the standard output
               
XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat());
                outputter.output
(document, System.out);
         
}
         
catch (Exception e) {
               
e.printStackTrace();
         
}
    }


   
public static void main(String[] args){
         
new JDOMDemo().createXmlWithInternalDocType();
   
}

}

The output is the following:

   <?xml version="1.0" encoding="UTF-8"?>
   <!DOCTYPE HOTEL [
   <!ELEMENT HOTEL (ROOM+)>
   <!ELEMENT ROOM (NUMBER, CATEGORY, BED+, FLOOR, LIVING_ROOM*, KITCHENETTE*, JACUZZI?)>
   <!ELEMENT NUMBER (#PCDATA)>
   <!ELEMENT CATEGORY (#PCDATA)>
   <!ELEMENT BED (#PCDATA)>
   <!ELEMENT FLOOR (#PCDATA)>
   <!ELEMENT LIVING_ROOM (#PCDATA)>
   <!ELEMENT KITCHENETTE (#PCDATA)>
   <!ELEMENT JACUZZI (#PCDATA)>
   <!ELEMENT AIR_CONDITIONING (TABLE_FANS | AIR_CONDITIONERS)>
   <!ELEMENT TABLE_FANS (#PCDATA)>
   <!ELEMENT AIR_CONDITIONERS (#PCDATA)>
   <!ATTLIST HOTEL name CDATA #IMPLIED>
   <!ATTLIST HOTEL starRating CDATA #IMPLIED>
   ]>
   <HOTEL>
            <ROOM>
                     <NUMBER>17</NUMBER>
                     <CATEGORY>STANDARD</CATEGORY>
                     <BED>DOUBLE SIZE</BED>
                     <FLOOR>5</FLOOR>
                     <AIR_CONDITIONING>
                              <TABLE_FANS>2</TABLE_FANS>
                     </AIR_CONDITIONING>
            </ROOM>
   </HOTEL>

A key point to note is that when creating an XML document from Java code, JDOM allows you to declare a DTD but it does not use the declared DTD to validate the associated XML document. JDOM only guarantees that XML documents are well formed. The only way to validate XML against a DTD file with JDOM is by parsing XML with DTD validation activated.


You are here :  JavaPerspective.com  >   Advanced Tutorials  >   3. XML processing with JDOM  >   3.13. Working with DTDs
Next tutorial :  JavaPerspective.com  >   Advanced Tutorials  >   3. XML processing with JDOM  >   3.14. JDOM and DOM integration

Copyright © 2013. JavaPerspective.com. All rights reserved.  ( Terms | Contact | About ) 
Java is a trademark of Oracle Corporation
Image 1 Image 2 Image 3 Image 4 Image 5 Image 6 Image 7