xs:任何包装器xml架构验证

时间:2012-05-10 06:34:24

标签: xml xsd

您好我正在尝试找到一种方法来开发扩展另一个模式验证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元素。

提前致谢!

3 个答案:

答案 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”来验证以该元素为根的子树。