xom-interest AT lists.ibiblio.org
Subject: XOM API for Processing XML with Java
List archive
[XOM-interest] nu.xom.URIUtil.relativize() fragility prevents round-tripping
- From: Wolfgang Hoschek <wolfgang.hoschek AT mac.com>
- To: xom-interest AT lists.ibiblio.org
- Subject: [XOM-interest] nu.xom.URIUtil.relativize() fragility prevents round-tripping
- Date: Fri, 24 Mar 2006 19:35:58 -0800
nu.xom.URIUtil.relativize(documentURL, systemID) is a bit fragile which in turn means that some documents can't be round-tripped. To start out with
1) nu.xom.URIUtil.relativize(documentURL, systemID) is a bit fragile:
String documentURL="file:///Users/hoschek/unix/devel/xom/../xom-1.2/ data/pe.xml"
String systemID= "file:///Users/hoschek/unix/devel/xom-1.2/data/ pe.txt"
System.out.println(nu.xom.URIUtil.relativize(documentURL, systemID))
yields the following bogus output
1.2/data/pe.txt
This relative URL does not exist in the file system, of course.
2) This fragility in turn means that nu.xom.XOMHandler has an incompatibility bug with xerces-2.7.0 and 2.8.1 (but interestingly not with 2.6.2 because it reports systemIDs in a slightly different format) wrt. external entity declarations. To see that, add some print diagnostics to XOMHandler.externalEntityDecl()
public void externalEntityDecl(String name,
String publicID, String systemID) {
System.out.println("3name="+name+", publicID="+publicID+", systemID="+systemID);
if (inInternalSubset() && doctype != null) {
internalDTDSubset.append(" <!ENTITY ");
if (name.startsWith("%")) {
internalDTDSubset.append("% ");
internalDTDSubset.append(name.substring(1));
}
else {
internalDTDSubset.append(name);
}
if (locator != null && URIUtil.isAbsolute(systemID)) {
String documentURL = locator.getSystemId();
System.out.println("systemID1="+systemID);
System.out.println("docURL1="+documentURL);
// work around Crimson style file:/root URLs
if (documentURL != null) {
if (documentURL.startsWith("file:/") && ! documentURL.startsWith("file:///")) {
documentURL = "file://" + documentURL.substring(5);
System.out.println("docURL2="+documentURL);
}
if (systemID.startsWith("file:/") && ! systemID.startsWith("file:///")) {
systemID = "file://" + systemID.substring(5);
System.out.println("systemID2="+systemID);
}
System.out.println("normalizing (docURL,systemID) =\n"+documentURL+"\n"+systemID);
systemID = URIUtil.relativize(documentURL, systemID);
System.out.println("systemID3="+systemID);
}
}
if (publicID != null) {
internalDTDSubset.append(" PUBLIC \"");
internalDTDSubset.append(publicID);
internalDTDSubset.append("\" \"");
internalDTDSubset.append(systemID);
}
else {
// need to escape system ID????
internalDTDSubset.append(" SYSTEM \"");
internalDTDSubset.append(systemID);
}
internalDTDSubset.append("\">\n");
}
}
Now run something like this with xerces-2.8.0:
public class XOMExternalEntityTest {
public static void main(String[] args) throws Exception {
String file = args[0];
// String file = "/Users/hoschek/unix/devel/nux/../nuxtestdata/XOM/ data/pe.xml";
// String file = "/Users/hoschek/unix/devel/nux/nuxtestdata/XOM/data/ pe.xml";
Document doc = new Builder().build(new File(args[0]));
System.out.println(doc.toXML());
}
}
[hoschek /Users/hoschek/unix/devel/xom]
export JAVA_OPTS='-Djava.endorsed.dirs=/Users/hoschek/unix/java/share/ apache/xerces-2.8.0/'
[hoschek /Users/hoschek/unix/devel/xom] fire-java nux.xom.sandbox.XOMExternalEntityTest /Users/hoschek/unix/devel/ xom/../xom-1.2/data/pe.xml
3name=%ccl, publicID=null, systemID=file:///Users/hoschek/unix/devel/ xom-1.2/data/pe.txt
systemID1=file:///Users/hoschek/unix/devel/xom-1.2/data/pe.txt
docURL1=file:///Users/hoschek/unix/devel/xom/../xom-1.2/data/pe.xml
normalizing (docURL,systemID)=
file:///Users/hoschek/unix/devel/xom/../xom-1.2/data/pe.xml
file:///Users/hoschek/unix/devel/xom-1.2/data/pe.txt
systemID3=1.2/data/pe.txt
<?xml version="1.0"?>
<!DOCTYPE doc SYSTEM "pe.dtd" [
<!ENTITY % ccl SYSTEM "1.2/data/pe.txt">
]>
<doc />
[hoschek /Users/hoschek/unix/devel/xom]
3) Again, "1.2/data/pe.txt" is bogus. This in turn means that the document can't be round-tripped. Serializing the document and trying to reparse that will yield to an an exception like this:
Exception in thread "main" java.io.FileNotFoundException:
<some bogus path trailing in /1.2/data/pe.txt goes here> (No such file or directory)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.<init>(FileInputStream.java:106)
at java.io.FileInputStream.<init>(FileInputStream.java:66)
at sun.net.www.protocol.file.FileURLConnection.connect (FileURLConnection.java:69)
at sun.net.www.protocol.file.FileURLConnection.getInputStream (FileURLConnection.java:156)
at org.apache.xerces.impl.XMLEntityManager.setupCurrentEntity (Unknown Source)
at org.apache.xerces.impl.XMLEntityManager.startEntity (Unknown Source)
at org.apache.xerces.impl.XMLEntityManager.startEntity (Unknown Source)
at org.apache.xerces.impl.XMLDTDScannerImpl.startPE(Unknown Source)
at org.apache.xerces.impl.XMLDTDScannerImpl.skipSeparator (Unknown Source)
at org.apache.xerces.impl.XMLDTDScannerImpl.scanDecls (Unknown Source)
at org.apache.xerces.impl.XMLDTDScannerImpl.scanDTDExternalSubset (Unknown Source)
at org.apache.xerces.impl.XMLDocumentScannerImpl $DTDDispatcher.dispatch(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument (Unknown Source)
at org.apache.xerces.parsers.DTDConfiguration.parse(Unknown Source)
at org.apache.xerces.parsers.DTDConfiguration.parse(Unknown Source)
at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
at nu.xom.Builder.build(Builder.java:1138)
at nu.xom.Builder.build(Builder.java:625)
voila,
Wolfgang.
-
[XOM-interest] nu.xom.URIUtil.relativize() fragility prevents round-tripping,
Wolfgang Hoschek, 03/24/2006
- Re: [XOM-interest] nu.xom.URIUtil.relativize() fragility prevents round-tripping, Elliotte Harold, 03/29/2006
Archive powered by MHonArc 2.6.24.