4

Trying to do subject.

I'm trying to use xsd from file(schemasource = 1) and from clob (schemasource = 0). I have two xsd schemas common_types.xsd and migom.xsd. second includes first. The problem is that when I'm using common_types schema from file I get error

ORA-29532: Java call terminated by uncaught Java exception: oracle.xml.parser.v2.XMLParseException: An internal error condition occurred.

and when I validate xml against only first schema has being read from clob I get success, but when I add second xsd, i get the same error, which says nothing at all.

create or replace and compile java source named XmlTools AS
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.XMLReader;

import org.xml.sax.InputSource;
import oracle.sql.CLOB;
import java.io.IOException;
import org.xml.sax.SAXException;
import java.sql.SQLException;
import java.lang.IllegalArgumentException;
import oracle.xml.parser.v2.XMLParseException;
import javax.xml.parsers.ParserConfigurationException;

import java.io.*;

public class XmlValidator
{

  static final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
  static final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema"; 
  static final String JAXP_SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource";


  public static void ValidateDocument(int schemasource, oracle.sql.CLOB schemadoc, oracle.sql.CLOB schemadoc1, oracle.sql.CLOB xmldoc) throws SAXException, IOException, SQLException, ParserConfigurationException, XMLParseException, IllegalArgumentException {


    try
          {              

            File myfile = new File(".//XML//common_types.xsd");
            if (myfile.exists())
            {
                Serv.log("ValidateDocument", "file size" + Long.toString(myfile.length()));
            }
            /*else
            {
                Serv.log("ValidateDocument", "file doesn't exists" );
            }*/

            Serv.log("ValidateDocument", "1" );
            SAXParserFactory factory = SAXParserFactory.newInstance();
            factory.setValidating(true);
            factory.setNamespaceAware(true);

            Serv.log("ValidateDocument", "2" );        
            SAXParser saxParser = factory.newSAXParser();
            saxParser.setProperty(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA);

            if (schemasource == 0)
            {
                InputSource schemaIs = new InputSource(schemadoc.getCharacterStream());        
                InputSource schemaIs1 = new InputSource(schemadoc1.getCharacterStream());  

                InputSource[] schemas = {schemaIs, schemaIs1};

                //saxParser.setProperty(JAXP_SCHEMA_SOURCE,   schemaIs); 
                saxParser.setProperty(JAXP_SCHEMA_SOURCE,   schemas); 
            }
            else
            {            
                saxParser.setProperty(JAXP_SCHEMA_SOURCE,   ".//XML//common_types.xsd"); 
            }
            XMLReader reader = saxParser.getXMLReader();

            //Получаем входной XML документ
            InputSource documentIs = new InputSource(xmldoc.getCharacterStream());
            Serv.log("ValidateDocument", "3" );          
            //Запуск разбора
            reader.parse(documentIs);
            Serv.log("ValidateDocument", "4" );          
            documentIs = null;     

           }
    /*catch (SAXException e) 
    {
        Serv.log("ValidateDocument", "SAXException" );
        Serv.log("ValidateDocument", "document is not valid because ");
        Serv.log("ValidateDocument", e.getMessage());
        throw(e);
    }*/          
    catch (ParserConfigurationException e) 
    {
        Serv.log("ValidateDocument", "ParserConfigurationException" );
        throw(e);
    }
    catch (IOException e) 
    {
        Serv.log("ValidateDocument", "IOException" );        
        throw(e);
    }

    catch (XMLParseException e)
    {
        Serv.log("ValidateDocument", "XMLParseException" );        
        Serv.log("ValidateDocument", e.getMessage());
        StackTraceElement[] stack = e.getStackTrace();        
        for (int i = 0; i < stack.length; i++)
        {
         Serv.log("stacktrace element no " + Integer.toString(i), "toString: " + stack[i].toString());
         Serv.log("stacktrace element no " + Integer.toString(i), "file name: " + stack[i].getFileName() + ", class name: " + stack[i].getClassName() + ", method name: " + stack[i].getMethodName() + ", line : " + stack[i].getLineNumber());
        }

        throw(e);
    }
    catch (IllegalArgumentException e)
    {
        Serv.log("ValidateDocument", "IllegalArgumentException" );        
        Serv.log("ValidateDocument", e.getMessage());
        throw(e);    
    }           


    }

}

additional information got from java stacktrace:

file name: XMLError.java, class name: oracle.xml.parser.v2.XMLError, method name: flushErrors1, line : 320 file name: NonValidatingParser.java, class name: oracle.xml.parser.v2.NonValidatingParser, method name: parseDocument, line : 300 file name: XMLParser.java, class name: oracle.xml.parser.v2.XMLParser, method name: parse, line : 200 file name: XMLTOOLS, class name: XmlValidator, method name: ValidateDocument, line : 86

my oracle version is Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod But my aim is to make it work on all versions starting from 9

Andrey Khataev
  • 1,303
  • 6
  • 20
  • 46

2 Answers2

0

UPDATE:

so, you loaded these files into the database as CLOBs. did you respect their xml encoding when you inserted them into the database?

jtahlborn
  • 52,909
  • 5
  • 76
  • 118
  • didn't help. i can say that if I merge these two schemas in one and put it as clob it leads to the same error. and because of that I think that matter is in second xsd, but I can't find out what exactly! all schemas - two standalone and merged one are well-formed and valid (checked in altova xmlspy) – Andrey Khataev Oct 17 '11 at 15:44
  • yes, I have pointed encoding in doth files – Andrey Khataev Oct 18 '11 at 06:45
  • right, and did you use that encoding when you converted them to Strings and insterted them into the database? – jtahlborn Oct 18 '11 at 12:03
  • Yes, I'm loading contents of file in proper encoding. Tried windows-1251 and utf-8 codepages. – Andrey Khataev Oct 18 '11 at 12:37
  • Just to be clear: your database is configured to use the same encoding as the String which is inserted? Otherwise Oracle can't interpret the contents of the Clob properly. I'm not at home with Oracle which seems to use the NLS environment variables, but in MySQL it's a parameter for CREATE DATABASE. – extraneon Nov 08 '11 at 19:45
0

As per your stacktrace, I saw that the NonValidatingParser was being used. Even though you had not mentioned that as an issue, it was unexpected. I do know that xmlparserv2 has a validating parser, so I had a look at the decompiled XMLParser in the xmlparserv2.jar (I have it with me since I work on OC4J).

The decompiled source is below. As you can see, the constructor assumes a non validation parser by default. The use of setProperty should switch it to a ValidatingParser but since that is not happening.

XMLParser()
{
    parser = new NonValidatingParser();
}

I could not find a setProperty method in the decompiled code. That is unusual but I haven't looked into it. To enable the xml validation I believe you will have to use a different API method. I believe the setAttribute method will do what you want.

public void setAttribute(String s, Object obj) throws IllegalArgumentException {

    ............
    if(s == "http://java.sun.com/xml/jaxp/properties/schemaSource")
        schemaSource = obj;
    else
    if(s == "http://java.sun.com/xml/jaxp/properties/schemaLanguage")
    {
        if(((String)obj).equals("http://www.w3.org/2001/XMLSchema"))
            setValidationMode(3);
        getSchemaValidator().setJAXP(true);
    }
    .......................
    attributes.put(s, obj);
}

I have used it in an application deployed on OC4J which I know is using the same parser. The code example is shown below

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

factory.setNamespaceAware(true);

factory.setValidating(true);

factory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema");

factory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaSource", ClassUtil.getResourceAsStream(schemaSourceLocation));

Hope this helps.

akhilss
  • 136
  • 5