2012-01-31 49 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 )。