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

1tuwyuhd  于 2023-10-16  发布在  Oracle
关注(0)|答案(2)|浏览(176)

我想问一个关于XML文档根据其相应的XML模式进行验证的问题,如果您能给予帮助,我将不胜感激。实际上,我刚刚开始学习XML模式(我完全是个初学者)。我已经购买了Priscilla Walmsley写的《XML模式》一书(第二版),其中介绍了XML模式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>

要根据上面提到的内容进行验证的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>

显然,[http://datypic.com/prod]是作者维护的一个网站,所以当我阅读这本书时,我不能在这个网站上添加或删除任何文件。因此,我需要将XML和XSD文档都放在本地硬盘上(我使用的是Linux Fedora Core 17 X86_64)。因此,我所做的就是将模式的内容放在名为example 'Example-01.xsd'的文件中,将XML内容放在名为'Example-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)语句:
/home/train/文档/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>

因此,如果您将新的XML内容与上面提到的示例进行比较,我唯一添加的是file:/home/train/Documents/myutl_file_dir/Example-01.xsdxsi: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

我从错误消息**Method invalid for non-schema based XML Documents**中了解到,Oracle只是忽略了我为模式文件定义的文件路径,它认为没有为这个XML文档声明任何模式。
有什么办法吗?我该怎么处理这个问题?

a0x5cqrl

a0x5cqrl1#

好吧,经过大量的谷歌搜索和感谢斯特凡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();

因此,正如您所看到的,在注册的模式和引用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')

这样,第一个问题就解决了,我的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>

我从'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/produpi *”注册了模式,只是因为在书中有一个文件名作为xsi:schemaLocation(prod.xsd)的第二部分,我认为我所要做的就是把模式内容放在一个名为Example-01.xsd的文件中,然后提供这个文档的文件URL,file://home/train/Documents/myutl_file_dir/Example-01.xsd。这确实是一件愚蠢的事情,因为当您通过调用DBMS_XMLSchema.registerSchema向Oracle注册模式时,Oracle会注册XML模式文档的内容。因此,Oracle需要的是在注册过程中使用的schemaURL,它允许唯一地查找和标识特定的模式。而这正是我的错误,我以为甲骨文正在寻找我的文件的物理位置.
结论:我已经通过targetNameSpace注册了模式:'http://datypic.com/prod'(好吧,这只是一个例子,我可以选择其他值)
因此,我的XML文档中schemaLocation的正确值是:

xsi:schemaLocation="http://datypic.com/prod prod.xsd 
                    http://datypic.com/prod prod.xsd"

这就解决了问题。
我希望这可以帮助那些遇到同样问题的人。
此致,
达里尤什

zf9nrax1

zf9nrax12#

该方法只能在基于架构的xmltype对象上调用。
在注册文档引用的XML模式之前,尝试删除并重新加载文档。
Oracle XML DB Developer's Guide
注册XML模式时,请记住,注册模式的操作不会影响已加载到Oracle XML DB资料档案库中的引用该XML模式的任何示例文档的状态。因为XML模式还没有注册,所以在加载这些示例文档时,它们不是基于模式的。注册架构后,它们仍然不基于架构。
您必须删除此类示例文档,并在注册架构后重新加载它们,以便获得基于架构的文档。
Oracle XML存储
您可以将模式放在引用它的XML所在的目录中。在这种情况下,您只需要像这样指定文件名:

xsi:noNamespaceSchemaLocation="Example-01.xsd"

(有效的相对URI引用)

相关问题