XML多模式位置

时间:2013-01-13 11:36:24

标签: xml xsd schema

我有一个XSD架构,但我需要它在两个可能的位置 - 一个用于开发(即我的PC和一个用于制作。

是否有一个简单的机制来执行此操作。例如,开发XML将是:

<?xml version="1.0" encoding="utf-8"?>
<Request xmlns="http://www.example.com/xml"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://dev.example.com/ Request.xsd\">
  <GetLocations />
</Request>

和生产

<?xml version="1.0" encoding="utf-8"?>
<Request xmlns="http://www.example.com/xml"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://www.example.com/ Request.xsd\">
  <GetLocations />
</Request>

这是为了让XSD <xs:include schemaLocation="DataTypes.xsd" />中的行能够获取正确的文件。

ADDEMDUM

让我们做一个例子

假设我使用PHP file_get_contents来检索XML文件。想要根据XSD文件(通过HTTP)进行检查。在该文件中,它有<xs:include schemaLocation="DataTypes.xdf" />。 PHP脚本如何知道从哪里获取此文件?

还有更多

我正在做以下

$xml = file_get_contents(<URL FOR XML FILE>);
$xsd = file_get_contents(<URL FOR XSD FILE>);

// The XSD has the include bit in it

$request = new DOMDocument();  
$request->loadXML($xml, LIBXML_NOBLANKS);
file_put_contents(<some temporary filename>, $xsd);
if (!$request->schemaValidate(<some temporary filename>))
{

etc...

问题是如何确保XSD文件正在拾取正确的include文件。我有两个架构副本。一个用于生产,另一个用于添加额外的东西。

5 个答案:

答案 0 :(得分:3)

解释schemaLocation的行为:它(XML)与XSD文件配对,该文件位于同一文件夹中(除非您指定了完整的文件路径/ URL)。现在你知道从哪里加载XSD文件了。

现在,在您的示例中,如果您通过XML解析器加载XML,那么schemaLocation将进入图片,其中每对中的第一个URI引用是命名空间名称,第二个是描述该命名空间的模式的位置。

如果您将XML加载为Doc并根据提供完整路径的XSD文件进行验证,则会覆盖schemaLocation

答案 1 :(得分:2)

import元素与include元素的作用相同。但是,import元素允许您从可能属于不同目标名称空间的相同/多个模式中访问组件。 这是语法:

<import id="ID" namespace="namespace" schemalocation="filename"/>

include元素用于包含或引用位于确定地址的外部模式。 这是语法:

<include id="ID" schemaLocation="anyURI" any attributes/>

include元素允许引用在相同目标名称空间的上下文中定义的任何外部模式。使用schema元素的targetNamespace属性声明模式的目标名称空间。 include元素中不需要namespace属性,因为包含和conatined模式的目标名称空间是相同的。

@ infantpro'aravind'已经解释了

schemaloaction行为

答案 2 :(得分:1)

PHP脚本将不知道包含的位置,除非您解析xsd文件以查找schemaLocation属性,该属性可能存在也可能不存在,因为它完全是可选的

将架构导入另一个架构时,不需要提供架构的路径。大多数XSD验证器将查找相同/子文件夹中的任何xsd文件,其命名空间与import语句匹配。有些人甚至会完全忽略schemaLocation attiribute。

答案 3 :(得分:1)

如果架构保持不变,您可以将其托管在公共位置,提供其绝对URI而不是相对URI,并且每个人都可以在那里找到它。

如果架构发生了变化(你说你正在向架构的开发版本添加“额外的东西”?那么什么样的东西?)你正在研究XML架构版本控制问题。除了能够找到架构之外,还有更多内容,请参阅this document on xml schema versioning了解一些建议。

答案 4 :(得分:0)

据我所知..
这样:

$xml = file_get_contents(<URL FOR XML FILE>);
$xsd = file_get_contents(<URL FOR XSD FILE>);
.............
...........
file_put_contents(<some temporary filename>, $xsd);
if (!$request->schemaValidate(<some temporary filename>))

将覆盖此:

<Request xmlns="http://www.example.com/xml"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://www.example.com/ Request.xsd\">

关于

  

如何确保XSD文件正在拾取正确的包含文件

没有现成的方法来检查和验证在schemaValidate中调用的XSD文件的文件路径/ URL。我想建议的是在开发环境中快速测试它(只是为了确定)。

在这两个位置保留不同的副本:
location1:从中选择XML的服务器路径,一个XSD将驻留在那里。
location2:在脚本中明确指定的XSD路径,第二个驻留在此处..

一个应该有错误的代码(有意),另一个应该有一个通过验证的正常代码。

解析你的XML并检查错误..错误的代码显然会抛出错误..

重复相同的交换两个XSD文件..

通过这个你会知道哪个人扮演这个角色:)

希望有所帮助......

更新

在我的asp.net网站上测试,这是我的发现:

将XML作为流输入传递:

<?xml version="1.0" encoding="utf-8"?>
<root
  xmlns="http://www.example.com/xml"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.example.com/ Request.xsd\">
  <branch>data</branch>
</root>

XSD也是如此:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://www.example.com/xml" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="root">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="branch" type="xs:string" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

验证失败,出现以下错误:

Cannot load the schema for the namespace 'http://www.example.com/' - Could not find file 'c:\windows\system32\inetsrv\Request.xsd\'.. Line: 1 Column:40

通过这种方式,它正在寻找Request.xsd中指定的schemaLocation。相对路径(c:\windows\system32\inetsrv\)是运行服务的地方。

希望这会有所帮助..