我有一个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
文件。我有两个架构副本。一个用于生产,另一个用于添加额外的东西。
答案 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\
)是运行服务的地方。
希望这会有所帮助..