1

您好我正在尝试找到一种方法来开发扩展另一个模式验证 XML 结构的模式。假设我们有 Schema A,它包含一个使用<xs:any>元素的扩展点所以我们有一个这样的模式:

来源.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 并引用原始模式吗?

扩展的.xml

<A>
  <B></B>
  <C></C>
</A>

我想创建一个模式来验证整个A(使用C)元素,而不必重写整个元素AType来合并C元素。我也不能使用redefine元素。

提前致谢!

4

3 回答 3

1

我认为Petru 的建议——以及我们实际使用的东西——是这样的:你定义

基础.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"/> 

简单的.xsd

<xs:include schemaLocation="Base.xsd"/>

<xs:group name="ATypeExtra">
  <xs:sequence>
  </xs:sequence>
</xs:group>

扩展的.xsd

<xs:include schemaLocation="Base.xsd"/>

<xs:group name="ATypeExtra">
  <xs:sequence>
     <xs:element name="C" type="CType"/>
  </xs:sequence>
</xs:group>

然后根据您想要的定义使用Simple.xsdExtended.xsd进行验证。

在我们的例子中,我们有一个核心架构的系统,该架构不能更改,但可以在不同的安装中扩展,因此我们将上面的Base.xsd等价物与所有xxxExtra组(和属性组)引用一起分发,然后在不同的环境中定义在每个安装方式。

于 2012-05-10T17:17:00.217 回答
1

在我看来,使用当前 1.0 规范(Michael 要求 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>

扩展的.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>
于 2012-05-10T11:36:08.247 回答
1

首先,xs:any 有一个 processContents 属性,其值为 strict、lax 或 skip。严格意味着“验证内容;如果找不到内容的架构定义,则将其视为无效”。Lax 的意思是“如果您可以找到内容的模式定义,则使用它来验证元素”。跳过意味着不验证。

有时这已经足够了。

如果您想要更多控制,那么您可以在应用程序控制下独立验证文档的某些部分。例如,您可以使用模式感知 XSLT 或 XQuery 轻松完成此操作。例如,在 XSLT 中,您可以导航到要验证的元素,然后使用 xsl:copy-of select="x" validation="strict" 来验证以该元素为根的子树。

于 2012-05-10T09:02:56.760 回答