【问题标题】:validating xml document in oracle's java source在 oracle 的 java 源代码中验证 xml 文档
【发布时间】:2011-12-09 09:35:24
【问题描述】:

尝试做主题。

我正在尝试使用来自文件(schemasource = 1)和来自 clob(schemasource = 0)的 xsd。 我有两个 xsd 模式 common_types.xsd 和 migom.xsd。第二包括第一。 问题是当我从文件中使用 common_types 模式时,我得到了错误

ORA-29532:Java 调用因未捕获的 Java 异常而终止:oracle.xml.parser.v2.XMLParseException:发生内部错误情况。

当我仅针对从 clob 读取的第一个模式验证 xml 时,我得到了成功,但是当我添加第二个 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 stacktrace 获得的附加信息:

文件名: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 版本是 Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod 但我的目标是让它适用于从 9 开始的所有版本

【问题讨论】:

    标签: java xml oracle validation xml-validation


    【解决方案1】:

    更新:

    所以,您将这些文件作为 CLOB 加载到数据库中。当您将它们插入数据库时​​,您尊重它们的 xml 编码吗?

    【讨论】:

    • 没有帮助。我可以说,如果我将这两个模式合并为一个并将其作为 clob 会导致相同的错误。正因为如此,我认为这件事在第二个 xsd 中,但我不知道到底是什么!所有模式 - 两个独立和合并的一个格式正确且有效(在 altova xmlspy 中检查)
    • 是的,我已经在 doth 文件中指出了编码
    • 对,当您将它们转换为字符串并将它们插入数据库时​​,您是否使用了该编码?
    • 是的,我正在以正确的编码加载文件内容。尝试了 windows-1251 和 utf-8 代码页。
    • 要明确一点:您的数据库配置为使用与插入的字符串相同的编码?否则 Oracle 无法正确解释 Clob 的内容。我不喜欢使用 NLS 环境变量的 Oracle,但在 MySQL 中它是 CREATE DATABASE 的参数。
    【解决方案2】:

    根据您的堆栈跟踪,我看到正在使用 NonValidatingParser。尽管您没有提到这是一个问题,但这是出乎意料的。我确实知道 xmlparserv2 有一个验证解析器,所以我查看了 xmlparserv2.jar 中反编译的 XMLParser(因为我在 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 工厂 = 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));

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-12-18
      • 1970-01-01
      • 1970-01-01
      • 2014-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多