您好我正在尝试找到一种方法来开发扩展另一个模式验证XML结构的模式。
假设我们有Schema A,它包含一个使用<xs:any>
元素的扩展点
所以我们有这样的架构:
Source.xsd :
<xs:complexType name="AType">
<xs:complexContent>
<xs:sequence>
<xs:element name="B"/>
<xs:any/>
</xs:sequence>
</xs:complexContent>
</xs:complexType>
<xs:element name="A" type="AType"/>
我可以使用对原始模式的引用来创建另一个验证此XML的模式吗?
Extended.xml :
<A>
<B></B>
<C></C>
</A>
我想创建一个模式来验证整个A
(使用C
)元素,而不必重写整个AType
以合并C
元件。我也不能使用redefine
元素。
提前致谢!
答案 0 :(得分:1)
在我看来,使用当前1.0规范(迈克尔需要XSLT 2.0及更高版本)的最佳方法是使用替换组的头部而不是xs:any通配符。版本1.0将为您提供更广泛的互操作性,而不是软件堆栈的可用性。
与xs:any不同,对于替换组,您需要使用基类型锚定它。我建议把它变成一个复杂的类型。它可以是一个空的complexType定义,因此它不会携带任何“超额”行李。
验证只是将解析器指向包含替换组成员而不是基础成员的模式。
更新:添加样本XSD来说明;您的更新为SubstitutionGroupExample.xsd:
<?xml version="1.0" encoding="utf-8" ?>
<xs:schema targetNamespace="http://tempuri.org/XMLSchema.xsd" elementFormDefault="qualified" xmlns="http://tempuri.org/XMLSchema.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="AType">
<xs:sequence>
<xs:element name="B"/>
<xs:element ref="any" />
</xs:sequence>
</xs:complexType>
<xs:element name="A" type="AType"/>
<xs:complexType name="TAny" abstract="true"/>
<xs:element name="any" type="TAny" abstract="true"/>
</xs:schema>
Extended.xsd:
<?xml version="1.0" encoding="utf-8" ?>
<xs:schema targetNamespace="http://tempuri.org/XMLSchema.xsd/1" elementFormDefault="qualified" xmlns="http://tempuri.org/XMLSchema.xsd/1" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:base="http://tempuri.org/XMLSchema.xsd">
<xs:import namespace="http://tempuri.org/XMLSchema.xsd" schemaLocation="SubstitutionGroupExample.xsd"/>
<xs:element name="someAny" substitutionGroup="base:any">
<xs:complexType>
<xs:complexContent>
<xs:extension base="base:TAny">
<xs:sequence>
<xs:element name="new"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>
</xs:schema>
有效的XML(基于Extended.xsd):
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!-- Sample XML generated by QTAssistant (http://www.paschidev.com) -->
<A xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://tempuri.org/XMLSchema.xsd" xmlns:ext="http://tempuri.org/XMLSchema.xsd/1">
<B>anyType</B>
<ext:someAny>
<ext:new/>
</ext:someAny>
</A>
答案 1 :(得分:1)
我认为Petru的建议 - 以及我们实际使用的东西 - 是:你定义
<强> Base.xsd 强>
<xs:complexType name="AType">
<xs:complexContent>
<xs:sequence>
<xs:element name="B" type="BType"/>
<xs:group ref="ATypeExtra"/>
</xs:sequence>
</xs:complexContent>
</xs:complexType>
<xs:element name="A" type="AType"/>
<强> Simple.xsd 强>
<xs:include schemaLocation="Base.xsd"/>
<xs:group name="ATypeExtra">
<xs:sequence>
</xs:sequence>
</xs:group>
<强> Extended.xsd 强>
<xs:include schemaLocation="Base.xsd"/>
<xs:group name="ATypeExtra">
<xs:sequence>
<xs:element name="C" type="CType"/>
</xs:sequence>
</xs:group>
然后使用 Simple.xsd 或 Extended.xsd 进行验证,具体取决于您想要的定义。
在我们的案例中,我们有一个核心架构的系统,该架构不得更改,但可以在不同的安装中进行扩展,因此我们将所有{{1}分配给 Base.xsd 的等效内容。组(和属性组)引用,然后在每个安装中以不同的方式定义。
答案 2 :(得分:0)
首先,xs:any有一个processContents属性,其值为strict,lax或skip。严格意味着“验证内容;如果找不到内容的架构定义,则将其视为无效”。 Lax表示“如果您可以找到内容的模式定义,则使用它来验证元素”。跳过表示不验证。
有时候这就够了。
如果您想要更多控制权,那么您可以在应用程序控制下独立验证文档的各个部分。例如,您可以使用模式感知的XSLT或XQuery轻松完成此操作。例如,在XSLT中,您可以导航到要验证的元素,然后使用xsl:copy-of select =“x”validation =“strict”来验证以该元素为根的子树。