2

我有一个 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" />能够拾取正确的文件。

附录

让我们做一个例子

假设我使用 PHPfile_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文件。我有两个架构副本。一个用于生产,另一个用于添加额外的东西。

4

5 回答 5

3

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

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

如果您将 XML 作为 Doc 加载并针对提供完整路径的 XSD 文件进行验证,schemaLocation则将被覆盖。

于 2013-01-16T11:44:13.347 回答
2

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

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

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

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

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

@infantpro'aravind' 已经解释了 schemaloaction 行为

于 2013-02-24T12:24:36.197 回答
1

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

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

于 2013-01-14T07:53:45.600 回答
1

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

如果架构更改(您说您正在向架构的开发版本添加“额外的东西”?什么样的东西?)您正在查看 XML 架构版本控制问题。除了能够找到架构之外,还有更多内容,请参阅有关 xml 架构版本控制的文档以获取一些建议。

于 2013-02-20T15:54:08.487 回答
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. 我想建议的是在开发环境中快速测试它(只是为了确定)。

在这两个位置保留不同的副本:
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\) 是运行服务的位置。

希望这可以帮助..

于 2013-02-25T08:07:31.887 回答