проверка XML-документа в Java-источнике оракула - PullRequest
4 голосов
/ 17 октября 2011

пытаюсь сделать тему.

Я пытаюсь использовать xsd из файла (schemasource = 1) и из clob (schemasource = 0). У меня есть две схемы xsd common_types.xsd и migom.xsd. второе включает в себя первое. Проблема в том, что когда я использую схему common_types из файла, я получаю сообщение об ошибке

ORA-29532: Вызов Java завершен из-за необработанного исключения Java: oracle.xml.parser.v2.XMLParseException: возникла внутренняя ошибка.

и когда я проверяю xml на предмет того, что только первая схема читается из clob, я получаю успех, но когда я добавляю второй xsd, я получаю ту же ошибку, которая ничего не говорит.

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);    
    }           


    }

}

дополнительная информация, полученная из трассировки стека Java:

имя файла: XMLError.java, имя класса: oracle.xml.parser.v2.XMLError, имя метода: flushErrors1, строка: 320 имя файла: NonValidatingParser.java, имя класса: oracle.xml.parser.v2.NonValidatingParser, имя метода: parseDocument, строка: 300 имя файла: XMLParser.java, имя класса: oracle.xml.parser.v2.XMLParser, имя метода: parse, строка: 200 имя файла: XMLTOOLS, имя класса: XmlValidator, имя метода: ValidateDocument, строка: 86

Моя оракулярная версия - Oracle Database 10g Enterprise Edition, выпуск 10.2.0.1.0 - Prod Но моя цель - заставить его работать на всех версиях, начиная с 9

Ответы [ 2 ]

0 голосов
/ 09 ноября 2011

Что касается вашей трассировки стека, я увидел, что используется NonValidatingParser. Даже если вы не упомянули это как проблему, это было неожиданно. Я знаю, что xmlparserv2 имеет проверяющий парсер, поэтому я посмотрел декомпилированный XMLParser в xmlparserv2.jar (он у меня есть, так как я работаю на OC4J).

Декомпилированный источник находится ниже. Как вы можете видеть, конструктор предполагает, что парсер не проверяется по умолчанию. Использование setProperty должно переключить его на ValidatingParser, но так как этого не происходит.

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

Я не смог найти метод setProperty в декомпилированном коде. Это необычно, но я не изучал это. Я полагаю, что для включения проверки xml вам придется использовать другой метод API. Я считаю, что метод setAttribute будет делать то, что вы хотите.

public void setAttribute (String s, Object obj) генерирует исключение 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);
}

Я использовал его в приложении, развернутом на OC4J, которое, как я знаю, использует тот же парсер. Пример кода показан ниже

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance ();

factory.setNamespaceAware (истина);

* * Factory.setValidating тысячи двадцать-одина (истина); * * тысяча двадцать-дв

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));

Надеюсь, это поможет.

0 голосов
/ 17 октября 2011

UPDATE:

Итак, вы загрузили эти файлы в базу данных как CLOB. Вы уважали их кодировку xml, когда вставляли их в базу данных?

...