2016-04-21 136 views
3

如何將XSD 1.1模式自動轉換爲XSD 1.0模式,方法是剝離所有1.1功能並僅保留與XSD 1.0兼容的子集?以編程方式將XSD 1.1模式轉換爲XSD 1.0?

我意識到這會限制您可以利用的XSD 1.1功能的數量,但我想象的用例是一種架構,您可以在其中發佈XSD 1.1版本和更兼容的XSD 1.0版本,兩者都描述相同的數據結構,但1.1版本還有一些附加的<assert>數據完整性檢查。

回答

1

如果您想要發佈1.1架構和相關的1.0架構,那麼可能最簡單也是最好的方法是使用XSD 1.1規範中描述的vc:namespace。您可以使用vc:namespace來標記1.1功能,例如您提到的斷言(或包含它們的聲明),並提供1.0當量或接近當量的值。

我們所用的一個例子使用此來標記xs:assert從XSD 1.1規範爲1.1-只特徵:

<xs:complexType name="arrayType"> 
<xs:sequence> 
    <xs:element name="entry" minOccurs="0" maxOccurs="unbounded"/> 
</xs:sequence> 
<xs:attribute name="length" type="xs:int"/> 
<xs:assert test="@length eq fn:count(./entry)" 
    xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" 
    vc:minVersion="1.1"/> 
</xs:complexType> 

不限XSD 1.1處理器需要了解VC:命名空間和過濾器模式相應的文件(接受vc:minVersion小於或等於1.1,或者vc:maxVersion大於1.1等等)。所以具有vc:*屬性的模式文檔可以作爲1.1模式發佈。

一個符合1.0處理器可以進行更新,以瞭解VC:命名空間,但我不知道有什麼都有了。因此,對於1.0處理器的使用,模式文檔需要在他們看到之前進行過濾。

和kjhughes一樣,我認爲XSLT樣式表可能是您過濾的最佳選擇。但是使用vc:*命名空間可以很容易地進行可靠的操作,並且不需要模式創作者最小化1.1功能的使用以簡化轉換。

寫一個樣式表來執行必要的過濾很容易,但實際上你不必:有一個XSLT 1.0 stylesheet可以完成這個工作(完全公開;我寫了它)。曾經有一個工作online demo,但我看到,位腐爛已經開始,並且它似乎不適用於當前的瀏覽器;有空的時候我會解決它。 documentation可能仍然有用。

1

正如您所預料的那樣,沒有一般情況下的轉換是可能的。然而,鑑於你在控制v1.1 XSD,這是有希望的。 XSD v1.1 RecommendationAppendix G.1總結了與XSD v1.0相比的變化。簡而言之,不要依賴附錄G.1中描述的任何新的構造或行爲。

如果你留下清晰的比使用xsd:assert你提到,你可以使用一個簡單的XSLT轉換來維持從1.0 XSD映射到你的V1.1 XSD其他所有的變化:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" 
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="xsd:assert"/> 
</xsl:stylesheet>