2012-01-31 15 views
1

我希望能够对我的XML文件进行版本控制。我想要一个较旧的xsd文件能够验证接收到的XML文件的较新版本。带有跳过行为属性的版本控制的XSD

为此,我将使用版本属性来保护未知的xml标签。

问题:如何根据版本属性让xsd跳过XML的一部分?在下面的例子中我想的XSD能够验证任何标签与版本1和2,但不是3

场景:

<MYXML> 
    <SOME_XML version="1"> 
     <SOME_VERSION_1_DATA>this_is_data_only_for_version_1</SOME_VERSION_1_DATA> 
    </SOME_XML> 
    <SOME_XML version="2"> 
     <SOME_VERSION_2_DATA>this_is_data_only_for_version_2</SOME_VERSION_2_DATA> 
    </SOME_XML> 
    <SOME_XML version="3"> 
     <SOME_VERSION_3_DATA>this_is_data_only_for_version_3</SOME_VERSION_3_DATA> 
    </SOME_XML> 
</MYXML> 


<xs:complexType name="SOME_XML"> 
    <xs:sequence> 
     <xs:element minOccurs="0" maxOccurs="1" name="SOME_VERSION_1_DATA" type="xs:string"/> 
     <xs:element minOccurs="0" maxOccurs="1" name="SOME_VERSION_2_DATA" type="xs:string"/> 
    </xs:sequence> 
    <xs:attribute ref="version"/> 
</xs:complexType> 

<xs:attribute name="version"> 
    <xs:simpleType> 
    <xs:restriction base="xs:integer"> 
     <xs:enumeration value="1"/> 
     <xs:enumeration value="2"/> 
    </xs:restriction> 
    <xs:anyAttribute processContents="skip"/> <-- SKIP the attribute if NOT 1 ro 2? 
    </xs:simpleType> 
</xs:attribute> 

回答

1

我不知道如何直接回答你的问题,使用跳过XML的特定细节。
如果在您的环境中可能,我建议xslt将跳过版本3文件的原始XML,并验证XLST生成的输出。

XSLT,同时舍弃与@atribute版本== 3

<xsl:template match="*"> 
    <xsl:if test="@version != '3'"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:if> 
</xsl:template> 
<xsl:template match="@*|text()|comment()|processing-instruction()"> 
    <xsl:copy-of select="."/> 
</xsl:template> 

注意到,XSLT写成的,它不是为给定的输入测试节点拷贝整个文件。

0

我不会使用属性,因为属性不能“改变”内容模型。如果您考虑使您的应用程序以“向前兼容”的方式处理XML(即,使用旧的XSD来处理新内容),那么我宁愿使用强制版本元素,然后是可选的xsd:any - 全部与一些混合设计规则。

简而言之,您需要使用这种设置才能处理唯一的粒子属性约束(或换句话说,解析器无法预见到的“约束”是什么在XSD中)。

最初,您甚至可以在没有强制性版本标签的情况下启动,只需将可选的xsd:any添加到您的可扩展性“place”所在的位置。随着后续版本对内容进行细化,您可能需要添加此强制版本标记(再次处理UPA),然后再添加精制内容,然后再次添加可选的xsd:any。

一般来说,还有其他一些事情需要考虑,例如在XSD中使用类型扩展/限制以及它可能对前向兼容性方案(如我刚刚描述的那种)的影响(请阅读this on SO )。