我想问一个关于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>
要针对上述内容验证的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(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和&amp; 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.xsd at 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
我从错误消息'对非基于模式的XML文档无效的方法中理解的是,oracle只是忽略了我为模式文件定义的文件路径,它认为没有为此XML文档声明的任何模式。
有什么想法吗?我该如何处理这个问题?
提前致谢,
Dariyoosh
答案 0 :(得分: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();
因此,您可以看到注册的架构与引用我的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/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"
这解决了这个问题。
我希望这可以帮助那些遇到同样问题的人。
此致
Dariyoosh
答案 1 :(得分:0)
只能在基于模式的 xmltype对象上调用该方法。
在注册他们引用的XML模式之前,尝试删除并重新加载文档。
Oracle XML DB Developer's Guide:
注册XML架构时,请记住该行为 注册模式对任何实例的状态都没有影响 已加载到Oracle XML DB Repository中的文档引用 XML架构。因为XML模式尚未注册,所以 实例文档在加载时是非基于模式的。 他们 在注册架构后,它仍然是非基于架构的。
您必须删除此类实例文档,然后重新加载它们 注册模式,以获取基于模式的文档。
您可以将架构放在与引用它的XML相同的目录中。在这种情况下,您只需要指定文件名,如下所示:
xsi:noNamespaceSchemaLocation="Example-01.xsd"
(有效的相对URI引用)