2012-11-04 35 views
7

我想问一个关于XML文档验证的问题,以及它相应的XML模式,如果您能帮我一把,我将不胜感激。其实,我刚开始学习XML模式(我完全是一个初学者)。我购买了由Priscilla Walmsley(2nd Edition)编写的书“Definitive XML Schema”,该书介绍了XML Schema 1.1(我认为它是最新版本)。Oracle可以使用本地文件系统上的XSD模式验证XML吗?

现在的问题是,在本书的所有示例和实践中,架构文件的名称空间和位置都是使用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-01.xsd”的文件中,并将XML内容放在名为“Example-01.xml”的文件中。

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

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

我创建了一个目录中的Oracle(通过创建目录)声明:

/家庭/火车/文档/ 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内容,我添加的唯一的事情就是文件:/ //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 

我从错误信息“方法无效,不能用于非懂什么基于模式的XML文档'是oracle已经简单地忽略了我为模式文件定义的文件路径,并且它认为没有为这个XML文档声明任何模式。

有什么想法?我该如何处理这个问题?

由于提前,

Dariyoosh

回答

7

OK,很多谷歌搜索,并感谢斯特凡nebesnak后”评论我发现了两个问题导致错误:

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

因此,大家可以看到有注册模式和引用我的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

If the target XML schema declares a target namespace, then the schemaLocation attribute is used to identify the XML schema. The value of this attribute is a pair of values separated by a space:

  • the value of the target namespace declared in the XML schema
  • the schema location hint, the unique identifier passed to procedure DBMS_XMLSCHEMA.registerSchema when the schema is registered with the database

而这恰恰是我没有做过的事情,我已经注册了“HTTP模式:// datypic。 com/prod',只是因为在本书中有一个文件名作为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,它允许唯一地查找和识别特定的模式。而这正是我认为oracle正在寻找我的文件的物理位置的错误。

结论:我从前的targetNamespace注册的模式:“http://datypic.com/prod”(当然,这只是一个例子,我可以选择其他值)

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

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

这就解决了这个问题。

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

问候,

Dariyoosh

0

该方法仅可以在基于模式的XMLType对象上调用。

在注册他们引用的XML模式之前,尝试删除并重新加载文档。

Oracle XML DB Developer's Guide

When you register an XML schema, keep in mind that the act of registering a schema has no effect on the status of any instance documents already loaded into Oracle XML DB Repository that reference the XML schema. Because the XML schema was not yet registered, such instance documents were non-schema-based when they were loaded. They remain non-schema-based after the schema is registered.

You must delete such instance documents, and reload them after registering the schema, in order to obtain schema-based documents.

Oracle XML Storage Tutorial

您可以将架构放置在与引用它的XML相同的目录中。在这种情况下,你只需要到指定的文件名是这样的:

xsi:noNamespaceSchemaLocation="Example-01.xsd" 

(有效相对URI参考)

+0

那么就像你说的,我改变了XML文档类似这样 但是我又得到了同样的错误。 – dariyoosh

+0

@ stefan nebesnak我使用targetNameSpace,因此xsi:noNamespaceSchemaLocation不适用于此问题。也只有模式是内置的(我的意思是注册到数据库中),XML文档只是一个局部的XMLType对象,其范围仅限于本地的DECLARE ... BEGIN ... END; PL/SQL块,因此不需要删除和重新加载文档,因为它们不是内置的。然而,我感谢你的评论(我不知道)和链接 – dariyoosh

相关问题