xs:any wrapper xml schema validation

冷暖自知 提交于 2019-12-24 08:35:59

问题


Hi I'm trying to find a way to develop a schema that extends another schema validate XML structures. Lets say we have Schema A and it contains an extension point using the <xs:any> element So that we have a schema like this:

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"/>

Can I make another schema that will validate this XML with a reference to the original schema?

Extended.xml:

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

I would like to create a schema that will validate the whole A (with the C) element without me having to rewrite the whole AType to incorporate the C element. I also can't use the redefine element.

Thanks in advance!


回答1:


In my opinion, the best way using current 1.0 specs (Michael's requires XSLT 2.0 and up) would be for you to use the head of a substitution group instead of the xs:any wildcard. Version 1.0 would give you wider interoperability vis-a-vis availability of the software stack.

Unlike xs:any, with substitution groups you need to anchor it with a base type. I recommend to make it a complex type. It can be an empty complexType definition, so that it doesn't carry any "excess" baggage.

Validation would then simply be to point the parser to the schema containing the members of the substitution group instead of the base one.

UPDATE: adding sample XSD to illustrate; yours updated as 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>

A valid XML (based on 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>



回答2:


What I think Petru is suggesting - and something we actually use - is this: you define

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>

and then use either Simple.xsd or Extended.xsd for the validation depending on which definition you want.

In our case we have a system with a core schema that must not change but can be extended in different installations, so we distribute the equivalent of Base.xsd above with all the xxxExtra groups (and attribute groups) references, that are then defined in different ways in each installation.




回答3:


First, xs:any has a processContents attribute with values strict, lax, or skip. Strict means "validate the content; if you can't find a schema definition for the content treat it as invalid". Lax means "if you can find a schema definition for the content, then use it to validate the element". Skip means don't validate.

Sometimes this will be enough.

If you want more control, then you can validate parts of a document independently under application control. For example, you can do this readily using schema-aware XSLT or XQuery. In XSLT, for example, you can navigate to an element you want to validate and then use xsl:copy-of select="x" validation="strict" to validate the subtree rooted at that element.



来源:https://stackoverflow.com/questions/10528634/xsany-wrapper-xml-schema-validation

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!