I'm writing a new set of parsers for my company's B2B API using the DOM
under JAXP (Summer '02 release from Sun).
Typically, XML messages our applications receive will get a DTD Header
in them, which is plainly:
<!DOCTYPE Acknowledgement SYSTEM \"TMC_Ack.dtd\">
By default, I found that JAXP was turning the systemId into a URI which
was:
file:///usr/local/tmc/TMC_Ack.dtd
(/usr/local/tmc being the home directory of the user running the App).
This being quite obviously incorrect, I constructed an entity resolved
which reads a system configuration value that contains the base
directory for DTDs, and returns an input source pointing to the proper
DTD:
package com.themunicenter.b2b.xml;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import com.muni.util.logger.*;
import java.io.File;
public class B2BEntityResolver implements EntityResolver {
public InputSource resolveEntity (String publicId, String systemId)
{
TMCLogger log = TMCLogger.getLogInstance("B2BEntityResolver");
File fSID = new File(systemId);
String f = fSID.getName();
String DTDBase = com.muni.util.MCProps.DTDBASE;
String correctDTD = "file://" + DTDBase + "/" + f;
log.info(correctDTD);
InputSource DTD = new InputSource(correctDTD);
log.info(DTD.getSystemId());
return DTD;
}
}
(TMCLogger is a log4j derived logger...MCProps simply reads in constants
- DTDBase in this case is
/usr/local/tmc/MuniCenter/com/themunicenter/b2b/xml/DTD)
My 'initialise and parse' block for the XML is as follows:
// Build factory
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
factory.setValidating(false);
log = TMCLogger.getLogInstance(this.getClass());
try {
DocumentBuilder builder = factory.newDocumentBuilder();
builder.setEntityResolver(new B2BEntityResolver());
ByteArrayInputStream xmlStream = createStream(xmlDoc);
document = builder.parse(xmlStream);
As you can see, I register my Entity Resolver...and it works to some
level.
I get this in my logfile:
2002-09-05 14:16:58,348 - |B2BEntityResolver| INFO [main]
(B2BEntityResolver.java:19) -
file:///usr/local/tmc/MuniCenter/com/themunicenter/b2b/xml/DTD/TMC_Ack.dtd
2002-09-05 14:16:58,656 - |com.themunicenter.b2b.xml.B2BAck| ERROR
[main] (B2BMsg.java:48) - *** Parsing error at Line 0; URI: Null Entity
File "file:///usr/local/tmc/MuniCenter.non-sales-corp/TMC_Ack.dtd" not
found.
at
org.apache.xerces.framework.XMLParser.reportError(XMLParser.java:975)
at
org.apache.xerces.readers.DefaultEntityHandler.startReadingFromExternalEntity(DefaultEntityHandler.java:768)
at
org.apache.xerces.readers.DefaultEntityHandler.startReadingFromExternalSubset(DefaultEntityHandler.java:566)
at
org.apache.xerces.framework.XMLDTDScanner.scanDoctypeDecl(XMLDTDScanner.java:1121)
at
org.apache.xerces.framework.XMLDocumentScanner.scanDoctypeDecl(XMLDocumentScanner.java:2176)
at
org.apache.xerces.framework.XMLDocumentScanner.access$0(XMLDocumentScanner.java:2133)
at
org.apache.xerces.framework.XMLDocumentScanner$XMLDeclDispatcher.dispatch(XMLDocumentScanner.java:775)
at
org.apache.xerces.framework.XMLDocumentScanner.parseSome(XMLDocumentScanner.java:380)
at
org.apache.xerces.framework.XMLParser.parse(XMLParser.java:861)
at
org.apache.xerces.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:123)
at
javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:138)
at com.themunicenter.b2b.xml.B2BMsg.<init>(B2BMsg.java:44)
at com.themunicenter.b2b.xml.B2BAck.<init>(B2BAck.java:40)
at com.themunicenter.b2b.xml.B2BAck.main(B2BAck.java:101)
2002-09-05 14:16:58,660 - |com.themunicenter.b2b.xml.B2BAck| ERROR
[main] (B2BMsg.java:57) - SAX Parse Exception
2002-09-05 14:16:58,661 - |com.themunicenter.b2b.xml.B2BAck| INFO
[main] (B2BAck.java:45) - Initialized B2BAck.parse()
The EntityResolver is being called, and is returning a proper
InputSource with the correct URI to the DTD.
But the parser seems to be ignoring the new location and I'm at a loss
why.
I need to get this to load the DTD without having to throw my DTDs in an
arbitrary directory as a 'hack'.
Anyone who can help?
-Brendan
--
Brendan W. McAdams | [EMAIL PROTECTED]
Senior Applications Developer | (646) 375-1140
TheMuniCenter, LLC | www.themunicenter.com
perl -e '$_="krJhruaesrltre c a cnp,ohet";$_.=$1,print$2while
s/(..)(.)//;'
"Always listen to experts. They'll tell you what can't be done, and why.
Then do it."
- Robert A. Heinlein
"I cannot make my days longer, so I strive to make them better."
- Henry David Thoreau
---------------------------------------------------------------------
In case of troubles, e-mail: [EMAIL PROTECTED]
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]