Oracle可以在本地文件系统上使用XSD架构验证XML吗?

dar*_*osh 8 xml oracle xsd plsql xml-parsing

我想问一个关于XML文档验证的问题,反对其相应的XML模式,如果你能帮助我,我将不胜感激.实际上,我刚开始学习XML模式(我完全是初学者).我已经购买了由Priscilla Walmsley(第2版)编写的"Definitive XML Schema"一书,该书介绍了XML Schema 1.1(我相信它是最新版本).

现在的问题是,在本书的所有示例和练习中,模式文件的名称空间和位置都是使用Web URL给出的.

这是本书的一个例子:

这是架构

<xs:schema  xmlns:xs="http://www.w3.org/2001/XMLSchema"
            targetNamespace="http://datypic.com/prod"
            xmlns:prod="http://datypic.com/prod">

    <xs:element name="product" type="prod:ProductType"/>
    <xs:complexType name="ProductType">
        <xs:sequence>
            <xs:element name="number" type="xs:integer"/>
            <xs:element name="size" type="prod:SizeType"/>
        </xs:sequence>
        <xs:attribute name="effDate" type="xs:date"/>
    </xs:complexType>
    <xs:simpleType name="SizeType">
        <xs:restriction base="xs:integer">
            <xs:minInclusive value="2"/>
            <xs:maxInclusive value="18"/>
        </xs:restriction>
    </xs:simpleType>
</xs:schema>
Run Code Online (Sandbox Code Playgroud)

并且要针对上述内容验证的XML内容是这样的

<prod:product xmlns:prod="http://datypic.com/prod" 
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://datypic.com/prod prod.xsd"
          effDate="2011-04-12">
    <number>557</number>
    <size>10</size>
</prod:product>
Run Code Online (Sandbox Code Playgroud)

显然,[http://datypic.com/prod]是由作者维护的网站,因此在我阅读本书时,我无法在本网站上添加或删除任何文件.因此,我需要将XML和XSD文档放在我的本地硬盘上(我使用的是Linux Fedora Core 17 X86_64).所以我所做的,就是把模式的内容在一个名为例如"文件示例- 01.xsd "和一个名为"文件的XML内容示例- 01.xml ".

我使用oracle PL/SQL包DBMS_XMLSCHEMA(Enterprise Edition 11.2.0.1.0)来首先注册模式,然后调用XMLType对象的validate方法,以便根据模式验证我的XML文档,类似于以下链接:

https://forums.oracle.com/forums/thread.jspa?messageID=2462207

我在oracle中创建了一个目录(通过CREATE DIRECTORY)语句:

/家庭/火车/文档/ myutl_file_dir /

我把我的XML和XSD文档放在哪里.以下是我如何更改上述XML内容以便在本地引用XSD

<prod:product xmlns:prod="http://datypic.com/prod" 
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://datypic.com/prod file:///home/train/Documents/myutl_file_dir/Example-01.xsd"
               effDate="2011-04-12">
    <number>557</number>
    <size>10</size>
</prod:product>
Run Code Online (Sandbox Code Playgroud)

所以,如果你比较与上面提到的例子中,新的XML内容,我添加的唯一的事情就是文件:///home/train/Documents/myutl_file_dir/Example-01.xsd在值的末尾XSI:的schemaLocation在为了引用本地硬盘.我找到了这个方法,这里:

http://lists.w3.org/Archives/Public/xmlschema-dev/2001Dec/0161.html

现在,问题是它不起作用.当我运行我的脚本以通过调用XMLType对象的schemaValidate()方法来验证文档时,这里是oracle错误消息:

BEGIN
*
ERROR at line 1:
ORA-19030: Method invalid for non-schema based XML Documents.
ORA-06512: at "SYS.XMLTYPE", line 354
ORA-06512: at "TRAIN2012.ZXML_PKG", line 176
ORA-06512: at line 2
Run Code Online (Sandbox Code Playgroud)

我从错误消息" 非基于模式的XML文档方法无效 "中理解是,oracle只是忽略了我为模式文件定义的文件路径,并认为没有为此XML文档声明任何模式.

任何的想法?我该如何处理这个问题?

提前致谢,

Dariyoosh

dar*_*osh 8

好吧,经过大量的谷歌搜索并感谢stefan nebesnak的评论我发现了两个导致错误的问题:

正如Stefan所提到的,第一个是DBMS_XMLSCHEMA.registerSchema只能应用于基于模式的文档.最初我在PL/SQL代码中所做的事情是这样的:

l_xml_file_content := XMLType('Here I put the content of my XML document')
l_xml_file_content.schemaValidate();
Run Code Online (Sandbox Code Playgroud)

因此,您可以看到注册的架构与引用我的XML文档的XMLType对象之间绝对没有任何关联.我必须做的是:

l_xml_file_content := 
   XMLType(
            'Here I put the content of my XML document'
          ).createSchemaBasedXML('and here I put the very same schema URL used during registereation while I registered the schema by calling the DBMS_XMLSCHEMA.registerSchema method')
Run Code Online (Sandbox Code Playgroud)

因此,第一个问题得到了解决,我的XML文档变成了基于模式的.

第二个问题是,在本书中,要根据模式验证的XML文档已按以下方式定义:

<prod:product xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xmlns:prod="http://datypic.com/prod"
              xsi:schemaLocation="http://datypic.com/prod prod.xsd" 
              effDate="2011-04-12">

    <number>557</number>
    <size>10</size>
</prod:product>
Run Code Online (Sandbox Code Playgroud)

我从' xsi:schemaLocation ="http://datypic.com/prod prod.xsd"中理解的是它的第一部分,即http://datypic.com/prod指的是targetNameSpace和由空格分隔的第二部分,即prod.xsd,用于指示模式文档的位置(作为URL),该位置为真.但我不知道的是,在oracle DBMS_XMLSCHEMA实现中,第二部分必须是用于通过调用DBMS_XMLSCHEMA.RegisterSchema方法注册模式的相同URL,否则它将无法工作.这里是oracle文档的链接,证实了这一点:

http://docs.oracle.com/cd/B19306_01/appdev.102/b14259/xdb03usg.htm#BABBGBDA

如果目标XML模式声明了目标名称空间,则schemaLocation属性用于标识XML模式.此属性的值是由空格分隔的一对值:

  • XML架构中声明的目标命名空间的值
  • 架构位置提示,在向数据库注册架构时传递给过程DBMS_XMLSCHEMA.registerSchema的唯一标识符

这正是我没有做过的,我用' http://datypic.com/prod ' 注册了模式,只是因为在书中有一个文件名作为xsi:schemaLocation(prod的第二部分) .xsd)我认为我所要做的就是将模式内容放在一个名为Example-01.xsd的文件中,然后将文件URL提供给该文档文件:/// home/train/Documents/myutl_file_dir /Example-01.xsd.这真是一件愚蠢的事情,因为当您通过调用DBMS_XMLSchema.registerSchema向oracle注册模式时,oracle会注册XML模式文档的内容.所以oracle需要的是注册期间使用的schemaURL,它允许查找和识别特定的模式.这正是我的错误,我以为oracle正在寻找我文件的物理位置.

结论:我已经通过targetNameSpace注册了模式:'http://datypic.com/prod'(嗯,这只是一个例子,我可以选择其他值)

所以,我的XML文档中schemaLocation的正确值是这样的:

xsi:schemaLocation="http://datypic.com/prod prod.xsd 
                    http://datypic.com/prod prod.xsd"
Run Code Online (Sandbox Code Playgroud)

这解决了这个问题.

我希望这可以帮助那些遇到同样问题的人.

问候,

Dariyoosh