Customizing External Entity Resolution

printer-friendly version of this section  Print  e-mail this section  E-Mail  add a public, group or private note  Add Note  add a bookmark about this section  Add Bookmark    

Java APIs for XML Kick Start
By Aoyon Chowdhury, Parag Choudhary

Table of Contents
Chapter 4.  Advanced Use of SAX


Customizing External Entity Resolution

So far, you have seen how the SAX parser resolves entities defined within the scope of the document. However, XML specifications provide the capability to refer and use entities that are defined outside the document. For example, an XML document can refer to an external DTD or an external parameter entity. A parameter entity enables an application to reuse parts of a DTD in multiple places in an XML document. This is analogous to general entities, which enable the text to be reused in multiple places in an XML document.

Normally, the SAX parser automatically processes the external entities. However, the SAX package provides an interface called EntityResolver, with which an application can implement its own customized handling for external entities.

You will now modify the CarParts.xml file and make it refer to an external DTD, as well as change the MyXMLHandler application to provide customized handling for the external entity resolution. The application, on finding the external DTD reference, will redirect it to a DTD description that you will provide in the application code itself.

Modifying the CarParts.xml File

To make the CarParts.xml file refer to a DTD defined in http://www.carpartsheaven.com/xml/dtds/carparts.dtd, make the change to CarParts.xml as listed in bold in Listing 4.7.

Listing 4.7 Adding DOCTYPE to CarParts.xml
<?xml version="1.0" encoding='us-ascii'?> <!DOCTYPE carparts SYSTEM "http://www.carpartsheaven.com/xml/dtds/carparts.dtd"> <carparts>     <?supplierformat format="X13" version="3.2"?>     <supplier name="&companyname;" URL="&companyweb;">     &companyname;     </supplier>     <engines>         <engine  type="Alpha37" capacity="2500" price="3500">             Engine 1         </engine>     </engines>     <carbodies>         <carbody  type="Tallboy" color="blue">             Car Body 1         </carbody>     </carbodies>     <wheels>         <wheel  type="X3527" price="120">             Wheel Set 1         </wheel>     </wheels>     <carstereos>         <carstereo  manufacturer="MagicSound" model="T76w" Price="500">             Car Stereo 1         </carstereo>     </carstereos>     <forCDATA><![CDATA[Special Text:  graphics/ccc.gif<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>SAMS  graphics/ccc.gifPublishing is the &best& <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>..]]> </forCDATA> </carparts> 

Next, we'll modify the MyXMLHandler application to resolve the reference to the external DTD to the DTD description provided in the application code. This is done by using the EntityResolver interface.

Using the EntityResolver

The following things need to be done to provide customized external entity resolution:

  1. Implement the EntityResolver interface.

  2. Register an instance of the EntityResovler interface with the parser using the setEntityResolver() method. The parser will then permit the application to intercept any external entities before including them.

  3. Provide the necessary application logic in the resolveEntity() method of the EntityResolver interface.

To provide customized external entity resolution in the MyXMLHandler application, do the following:

  1. Import the StringReader class. The StringReader is required to convert the string that holds the DTD information to an InputSource.

  2. Create an internal static class called MyEntityResolver that implements EntityResolver.

  3. Register an instance of the class with the parser.

  4. Create the DTD structure as a String in the MyEntityResolver class, and define the resolveEntity() method to redirect the parser to use this DTD structure instead of the external DTD reference.

First, import the StringReader class. To do so, add the following line listed in bold:

import javax.xml.parsers.*; import org.xml.sax.*; import org.xml.sax.helpers.*; import org.xml.sax.ext.LexicalHandler; import java.io.StringReader; 

Next, create the class that implements the EntityResolver. To do so, add the following lines listed in bold:

static class MyErrorHandler implements ErrorHandler {     .......... } static class MyEntityResolver implements EntityResolver {     public InputSource resolveEntity(java.lang.String publicId, java.lang.String systemId)             {             } } 

Next, register the class with the parser. To do so, add the following line listed in bold:

static public void main(String[] args) throws Exception {     .................... xmlReader.setProperty("http://xml.org/sax/properties/lexical-handler", new MyXMLHandler( graphics/ccc.gif));         /*Override the entity resolver*/         xmlReader.setEntityResolver(new MyEntityResolver());         /*set the error handler*/         xmlReader.setErrorHandler(new MyErrorHandler());     ...................... } 

Finally, create the DTD structure as a string in the MyEntityResolver class, and define the resolveEntity() method to redirect the parser to use this DTD structure instead of the external DTD reference. To do so, add the following lines listed in bold in Listing 4.8.

Listing 4.8 Implementing EntityResolver
static class MyEntityResolver implements EntityResolver { static String xmlDTD =                 "<!ENTITY  companyname \"Heaven Car Parts (TM)\">"+                 "<!ENTITY  companyweb \"http://carpartsheaven.com\">"+                 "<!ELEMENT carparts (supplier,engines,carbodies, wheels,carstereos, graphics/ccc.gifforCDATA)>"+                 "<!ELEMENT engines (engine+)>"+                 "<!ELEMENT carbodies (carbody+)>"+                 "<!ELEMENT wheels (wheel+)>"+                 "<!ELEMENT carstereos (carstereo+)>"+                 "<!ELEMENT forCDATA ANY>"+                 "<!ELEMENT supplier (#PCDATA)>"+                 "<!ATTLIST supplier"+                 "            name CDATA #REQUIRED"+                 "            URL CDATA #REQUIRED"+                 ">"+                 ""+                 "<!ELEMENT engine (#PCDATA)*>"+                 "<!ATTLIST engine"+                 "            id CDATA #REQUIRED"+                 "            type CDATA #REQUIRED"+                 "            capacity (1000 | 2000 | 2500 ) #REQUIRED"+                 "            price CDATA #IMPLIED"+                 "            text CDATA #IMPLIED"+                 ">"+                 "<!ELEMENT carbody (#PCDATA)*>"+                 "<!ATTLIST carbody"+                 "            id CDATA #REQUIRED"+                 "            type CDATA #REQUIRED"+                 "            color CDATA #REQUIRED"+                 ">"+                 "<!ELEMENT wheel (#PCDATA)*>"+                 "<!ATTLIST wheel"+                 "            id CDATA #REQUIRED"+                 "            type CDATA #REQUIRED"+                 "            price CDATA #IMPLIED"+                 "            size  (X | Y | Z) #IMPLIED"+                 ">"+                 "<!ELEMENT carstereo (#PCDATA)*>"+                 "<!ATTLIST carstereo"+                 "            id CDATA #REQUIRED"+                 "            manufacturer CDATA #REQUIRED"+                 "            model CDATA #REQUIRED"+                 "            Price CDATA #REQUIRED"+                 ">";         public InputSource resolveEntity(java.lang.String publicId, java.lang.String  graphics/ccc.gifsystemId)         {             if (systemId.equals ("http://www.carpartsheaven.com/xml/dtds/carparts.dtd"))             {                 System.out.println("Redirecting to local DTD for "+systemId);                 return new InputSource(new StringReader(xmlDTD));             }             else             {                     return null;             }         }     } 

The xmlDTD string contains the DTD structure for the CarParts.xml document. The resolveEntity() method checks whether the referenced DTD is http://www.carpartsheaven.com/xml/dtds/carparts.dtd, and then redirects the application to use the DTD defined in the application.

NOTE

The code discussed here is available in the example0403 folder. This folder also contains the sample CarParts.xml file.


You can now compile and run the program. The output should be similar to Listing 4.9. The output from the EntityResolver method is listed in bold. Also, the application is now using the DTD defined in the application code itself to validate the CarParts.xml document.

Listing 4.9 Output of MyXMLHandler with EntityResolver
Version 0403.0 of MyXMLHandler in example0403 Locator :file:///D:/sams_work/Java Api/Chapter 4- SAX APIs - Advanced Use/example0403/ graphics/ccc.gifCarParts.xml Start Document: -----Reading the document CarParts.xml with MyXMLHandler------ Starting DTD :http://www.carpartsheaven.com/xml/dtds/carparts.dtd Redirecting to local DTD for http://www.carpartsheaven.com/xml/dtds/carparts.dtd Starting entity :[dtd] Ending entity :[dtd] Ending DTD Location of event at line number :4 Start Element-> carparts     Total Number of Attributes: 0 Location of event at line number :6 Start Element-> supplier     Total Number of Attributes: 2         Attribute: name = Heaven Car Parts (TM)         Attribute: URL = http://carpartsheaven.com Characters: Starting entity :companyname Characters: Heaven Car Parts (TM) Ending entity :companyname Characters: End Element-> supplier Location of event at line number :9 Start Element-> engines     Total Number of Attributes: 0 Location of event at line number :10 Start Element-> engine     Price= 3500 Characters:             Engine 1 Characters: End Element-> engine End Element-> engines Location of event at line number :14 Start Element-> carbodies     Total Number of Attributes: 0 Location of event at line number :15 Start Element-> carbody     Total Number of Attributes: 3         Attribute: id = C32         Attribute: type = Tallboy         Attribute: color = blue Characters:             Car Body 1 Characters: End Element-> carbody End Element-> carbodies Location of event at line number :19 Start Element-> wheels     Total Number of Attributes: 0 Location of event at line number :20 Start Element-> wheel     Price= 120 Characters:             Wheel Set 1 Characters: End Element-> wheel End Element-> wheels Location of event at line number :24 Start Element-> carstereos     Total Number of Attributes: 0 Location of event at line number :25 Start Element-> carstereo     Total Number of Attributes: 4         Attribute: id = C2         Attribute: manufacturer = MagicSound         Attribute: model = T76w         Attribute: Price = 500 Characters:             Car Stereo 1 Characters: End Element-> carstereo End Element-> carstereos Location of event at line number :29 Start Element-> forCDATA     Total Number of Attributes: 0 Starting CDATA Section Characters: Special Text:  graphics/ccc.gif<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>SAMS  graphics/ccc.gifPublishing is the &best& <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>.. Ending CDATA Section End Element-> forCDATA End Element-> carparts End Document: ----------------Finished Reading the document------------------- 

printer-friendly version of this section  Print  e-mail this section  E-Mail  add a public, group or private note  Add Note  add a bookmark about this section  Add Bookmark    
Top

[0672324342/ch04lev1sec3]

 
 


JavaT APIs for XML Kick Start
JAX: Java APIs for XML Kick Start
ISBN: 0672324342
EAN: 2147483647
Year: 2002
Pages: 133

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net