You are viewing a plain text version of this content. The canonical link for it is here.
Posted to j-dev@xerces.apache.org by ji...@apache.org on 2004/04/12 23:25:51 UTC

[jira] Updated: (XERCERJ-412) Parser does not validate if entity resolver is used and XML does not define schemaLocation

The following issue has been updated:

    Updater: Serge Knystautas (mailto:sergek@lokitech.com)
       Date: Mon, 12 Apr 2004 2:24 PM
    Changes:
             Attachment changed from A-BAD-ORDER.xml
    ---------------------------------------------------------------------
For a full history of the issue, see:

  http://issues.apache.org/jira/browse/XERCERJ-412?page=history

---------------------------------------------------------------------
View the issue:
  http://issues.apache.org/jira/browse/XERCERJ-412

Here is an overview of the issue:
---------------------------------------------------------------------
        Key: XERCERJ-412
    Summary: Parser does not validate if entity resolver is used and XML does not define schemaLocation
       Type: Bug

     Status: Open

    Project: Xerces2-J

   Assignee: Xerces-J Developers Mailing List
   Reporter: rob anderson

    Created: Wed, 31 Jul 2002 11:20 AM
    Updated: Mon, 12 Apr 2004 2:24 PM
Environment: Operating System: Windows XP
Platform: PC

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)
            {
                throw new Exception(errors.toString());
            }
            System.out.println("\n\t\tWOW... Document is valid!!!!\n\n");
        }
        catch (Exception e)
        {
            System.out.println(
                "\n\t\tOops - bad document:-\n" + e.getMessage() + "\n\n");
        }
    }

    /* (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[] {
                                    config
                                        .getDocumentDefinitionLocation()
                                        .toString(),
                                    basename });
                    }
                    else
                    {
                        try
                        {
                            schemaURL =
                                new URL(new URL(schemaLocation), basename);
                            System.out.println(
                                "Schema location "
                                    + schemaLocation
                                    + " is a valid URL");
                        }
                        catch (MalformedURLException murle)
                        {
                            System.out.println(
                                "Schema location is relative, so "
                                    + "prepending default location ");
                            schemaURL =
                                buildURL(
                                    new String[] {
                                        config
                                            .getDocumentDefinitionLocation()
                                            .toString(),
                                        schemaLocation,
                                        basename });
                        }
                    }

                    //  Find the resource
                    InputStream in = null;
                    try
                    {
                        System.out.println(
                            "Looking for " + schemaURL.toExternalForm());
                        in = schemaURL.openStream();
                        if (in == null)
                        {
                            System.out.println(
                                "Failed, trying  to open resource "
                                    + schemaURL.toExternalForm()
                                    + " as a resource.");
                            return 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)
                    {
                        System.out.println(
                            "Could not locate a local document "
                                + "definition for "
                                + basename
                                + ". The default "
                                + "of "
                                + systemId
                                + " that was supplied with "
                                + "the original will be used. \n>>>>>>>This 
**may** "
                                + "not be correct");
                        return null;
                    }
                    finally
                    {
                    }
                }
                //  The config was bad!! sort it out
                catch (MalformedURLException murel)
                {
                    System.out.println(
                        "Could not build a URL for an document "
                            + "definition.\n"
                            + "The default document definition of '"
                            + systemId
                            + "' will be used.\nThis **may** not be 
correct.\n\n");
                    return null;
                }
            }
            else
                return null;
        }

        public URL buildURL(String[] elements) throws MalformedURLException
        {
            StringBuffer buf = new StringBuffer();
            for (int i = 0; i < elements.length; i++)
            {
                if (i > 0)
                    buf.append("/");
                String s = elements[i];
                if (s.startsWith("/"))
                    s = s.substring(1);
                if (s.endsWith("/"))
                    s = s.substring(0, s.length() - 1);
                buf.append(s);
            }
            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

http://www.ebis-xml.net/starterpack


---------------------------------------------------------------------
JIRA INFORMATION:
This message is automatically generated by JIRA.

If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa

If you want more information on JIRA, or have a bug to report see:
   http://www.atlassian.com/software/jira


---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-j-dev-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-j-dev-help@xml.apache.org