Details
-
Bug
-
Status: Open
-
Resolution: Unresolved
-
2.0.2
-
None
-
None
-
Operating System: Windows XP
Platform: PC
-
11326
Description
We need to assign an entity resolver during parsing, in order to use local
copies of schema/dtd's, therby, overidding what the user's document is
dictating.
A sample XML that I expect to FAIL (You will notice that only a namespace is
provided here, and that it has a 'BAD' <OrderDate>).
<?xml version="1.0"?>
<Order xmlns="urn:schemas-basda-org:2000:purchaseOrder:xdr:3.03">
<OrderHead>
<Schema>
<Version>String</Version>
</Schema>
<Parameters>
<Language>aa_AA</Language>
<DecimalSeparator>,</DecimalSeparator>
<Precision>3.14159</Precision>
</Parameters>
<OrderType>String</OrderType>
<OrderCurrency>
<Currency Code="String">String</Currency>
</OrderCurrency>
<Checksum>0</Checksum>
</OrderHead>
<OrderDate>BAD-DATE</OrderDate>
<Supplier>
<Party>String</Party>
</Supplier>
<OrderLine>
<LineNumber>0</LineNumber>
</OrderLine>
</Order>
-----------------------------------------------------------------------------
A sample XML that I expect to PASS is...
====
<?xml version="1.0"?>
<Order xmlns="urn:schemas-basda-org:2000:purchaseOrder:xdr:3.03">
<OrderHead>
<Schema>
<Version>String</Version>
</Schema>
<Parameters>
<Language>aa_AA</Language>
<DecimalSeparator>,</DecimalSeparator>
<Precision>3.14159</Precision>
</Parameters>
<OrderType>String</OrderType>
<OrderCurrency>
<Currency Code="String">String</Currency>
</OrderCurrency>
<Checksum>0</Checksum>
</OrderHead>
<OrderDate>2001-02-04</OrderDate>
<Supplier>
<Party>String</Party>
</Supplier>
<OrderLine>
<LineNumber>0</LineNumber>
</OrderLine>
</Order>
We assign an EntityResolver...
parser.setProperty("http://apache.org/xml/properties/schema/external-
schemaLocation", "urn:schemas-basda-org:2000:purchaseOrder:xdr:3.03 order-
v3.xsd");
However this appears to turn off validation, even though the entity resolver
finds the correct document.
--------------------------------------------------------------------------
We are also setting the following features: -
http://xml.org/sax/features/namespaces=true
http://xml.org/sax/features/namespace-prefixes=false
http://xml.org/sax/features/validation=true
http://apache.org/xml/features/validation/schema=true
http://apache.org/xml/features/validation/schema-full-checking=true
http://apache.org/xml/features/validation/dynamic=true
-----------------------------------------------------------------------
A (Windows - unfortunately) batch to run the test is...
@echo off
cls
echo Bad Order?==========================================================
java cp lib\xercesImpl.jar;lib\xmlParserAPIs.jar; TestEntityResolver A-BAD
ORDER.xml
echo Good Order?==========================================================
java cp lib\xercesImpl.jar;lib\xmlParserAPIs.jar; TestEntityResolver A-GOOD
ORDER.xml
//---------------------------------------------------------------------------
The java code is....
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Vector;
import org.xml.sax.*;
import org.xml.sax.helpers.XMLReaderFactory;
public class TestEntityResolver implements ErrorHandler, DTDHandler
{
private Config config = new Config();
private Vector errors = new Vector();
public static void main(String[] args)
{ new TestEntityResolver(args[0]); } public TestEntityResolver(String xmlFile)
{
try
{
XMLReader parser =
XMLReaderFactory.createXMLReader(
"org.apache.xerces.parsers.SAXParser");
TheEntityResolver entResolver =
new TheEntityResolver("xml/basda/xsd");
parser.setEntityResolver(entResolver);
parser.setErrorHandler(this);
parser.setDTDHandler(this);
//
parser.setProperty(
"http://apache.org/xml/properties/schema/external-
schemaLocation",
"urn:schemas-basda-org:2000:purchaseOrder:xdr:3.03 order-
v3.xsd");
//
parser.setFeature("http://xml.org/sax/features/namespaces", true);
parser.setFeature(
"http://xml.org/sax/features/namespace-prefixes",
false);
parser.setFeature("http://xml.org/sax/features/validation", true);
parser.setFeature(
"http://apache.org/xml/features/validation/schema",
true);
parser.setFeature(
"http://apache.org/xml/features/validation/schema-full-
checking",
true);
parser.setFeature(
"http://apache.org/xml/features/validation/dynamic",
true);
parser.parse(
new InputSource(new FileInputStream(new File(xmlFile))));
if (errors.size() > 0)
System.out.println("\n\t\tWOW... Document is valid!!!!\n\n");
}
catch (Exception e)
}
/* (non-Javadoc)
- @see org.xml.sax.ErrorHandler#error(SAXParseException)
*/
public void error(SAXParseException exception) throws SAXException { errors.add(exception.getMessage()); }
/* (non-Javadoc)
* @see org.xml.sax.ErrorHandler#fatalError(SAXParseException)
*/
public void fatalError(SAXParseException exception) throws SAXException
{ errors.add(exception.getMessage()); }
/* (non-Javadoc)
- @see org.xml.sax.ErrorHandler#warning(SAXParseException)
*/
public void warning(SAXParseException exception) throws SAXException { errors.add(exception.getMessage()); }
/* (non-Javadoc)
- @see org.xml.sax.DTDHandler#notationDecl(String, String, String)
*/
public void notationDecl(String name, String publicId, String systemId)
throws SAXException { System.out.println( "DTDHANDLER: notationDecl...name=" + name + " publicId+" + publicId + " systemId+" + systemId); }
/* (non-Javadoc)
- @see org.xml.sax.DTDHandler#unparsedEntityDecl(String, String, String,
String)
*/
public void unparsedEntityDecl(
String name,
String publicId,
String systemId,
String notationName)
throws SAXException { System.out.println( "DTDHANDLER: unparsedEntityDecl...name=" + name + " publicId+" + publicId + " systemId+" + systemId + " notationName=" + notationName); }
//-------------------------------------------------------------------------
------------------------------------------------------------------
/**
- This class would normally be from our factory
*/
class Config
{
public String getDocumentDefinitionLocation()
{ return "file:///c:/workspace/qdg/src"; }}
/**
- the entity resolver
*/
class TheEntityResolver implements EntityResolver
{
public TheEntityResolver(String schemaLocation) { this.schemaLocation = schemaLocation; }
public InputSource resolveEntity(String publicId, String systemId)
{
System.out.println(
"Resolve publicId=" + publicId + " systemId=" + systemId);
if (systemId != null && !systemId.equals(""))
{
int idx = systemId.lastIndexOf("/");
String basename = systemId;
if (idx > -1)
basename = systemId.substring(idx + 1);
System.out.println("Basename part of resource is " + basename);
// First of all, see if we already know about a document
definition of
// the same name
try
{
System.out.println(
"Local Document Definitions are in "
+ config.getDocumentDefinitionLocation());
// Build a URL for where our local schema's are help. If
the schema
// location specified was a URL anyway, then just use
that, otherwise
// append the schema location to the default document
definition
// location from the general configuration
URL schemaURL = null;
if (schemaLocation == null)
{
System.out.println(
"Schema location was not specified. "
+ "Using default of "
+ config.getDocumentDefinitionLocation()
+ "/"
+ basename);
schemaURL =
buildURL(
new String[]
);
}
else
{
try
catch (MalformedURLException murle)
{
System.out.println(
"Schema location is relative, so "
+ "prepending default location ");
schemaURL =
buildURL(
new String[]
);
}
}
// Find the resource
InputStream in = null;
try
{
System.out.println(
"Looking for " + schemaURL.toExternalForm());
in = schemaURL.openStream();
if (in == null)
System.out.println(
"Opened "
+ schemaURL.toExternalForm()
+ " (SYSTEMID="
+ systemId
+ " PUBLICID="
+ publicId
+ "). Will use this for "
+ basename
+ ".");
InputSource inSource = new InputSource(in);
inSource.setSystemId(systemId);
return inSource;
}
// There was no local copy, so revert back to the current
one
catch (IOException ioe)
finally
{
}
}
// The config was bad!! sort it out
catch (MalformedURLException murel)
}
else
return null;
}
public URL buildURL(String[] elements) throws MalformedURLException
{
StringBuffer buf = new StringBuffer();
for (int i = 0; i < elements.length; i++)
System.out.println("Building URL:" + buf.toString());
return new URL(buf.toString());
}
private String schemaLocation;
}
}
//----------------------------------------------------------------------------
I have not included the schema here - but they are available from