我希望能够对我的XML文件进行版本控制。我希望旧的xsd文件能够验证收到的XML文件的更新版本。
为此,我将使用版本属性保护未知的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>
答案 0 :(得分:1)
我不确定如何直接回答您的问题,使用从XML中删除特定详细信息 如果在您的环境中可行,我建议xslt转换原始XML,其中将跳过版本3文件,并验证XLST生成的输出。
XSLT复制整个文件,同时使用@atribute version == 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按原样编写,未针对给定输入进行测试。
答案 1 :(得分:0)
我不会为此使用属性,因为属性不能改变&#34;内容模型。如果您考虑使您的应用程序在&#34;前向兼容&#34;方式(即使用旧的XSD作为新内容),然后我宁愿使用强制版本元素,后面跟一个可选的xsd:any - 全部混合了一些设计规则。
总而言之,您需要这种设置才能处理独特的粒子归因约束(或者换句话说,解析器无法提前看出来的约束&#34;其中&# 34;它在XSD中)。
最初你甚至可以在没有强制版本标签的情况下开始,只需坚持一个可选的xsd:任何可扩展性的地方&#34;放置&#34;是。随后的版本改进内容,您可能必须添加此强制版本标记(再次,以处理UPA),然后是精炼内容,然后再添加可选的xsd:any。
一般情况下,还有其他事项需要考虑,例如在XSD中使用类型扩展/限制以及它可能对前向兼容性方案产生的影响,例如我刚刚描述的那个(请阅读) this on SO)。