2017-08-15 36 views
1

A具有描述XML對象(簡化的示例)的XSD架構:是否可以添加新的XML標籤以便它對XSD驗證是透明的?

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
      targetNamespace="http://my-custom-ns.com"> 
    <xs:element name="item"> 
     <xs:complexType> 
      <xs:sequence> 
       <xs:element name="active" type="xs:boolean"/> 
       <xs:element name="value" type="xs:string"/> 
      </xs:sequence> 
     </xs:complexType> 
    </xs:element> 
</xs:schema> 

即模式是內置在一個應用程序作爲資源和安裝在許多工作站。 該應用程序使用XML文件並根據此架構驗證它們。 這裏就是這樣一個XML的(簡體)例如:

<my:item xmlns:my="http://my-custom-ns.com"> 
    <active>true</active> 
    <value>foo</value> 
</my:item> 

現在,我想我的XML文件,而無需改變XSD得到一個新的元素(新標籤):

<my:item xmlns:my="http://my-custom-ns.com"> 
    <active>true</active> 
    <value>foo</value> 
    <tag>bar</tag> 
</my:item> 

我不會改變XSD,所以很明顯,驗證會在新標籤上失敗。 有沒有辦法讓XML中有一個新的標籤,以便它透明地「通過」驗證(即完全忽略)?

我嘗試添加在希望XSD驗證會忽略它的XML一個新的命名空間,但是這並沒有幫助:

<my:item xmlns:my="http://my-custom-ns.com" xmlns:new="http://new-ns.com"> 
    <active>true</active> 
    <value>foo</value> 
    <new:tag>bar</new:tag> 
</my:item> 

的背景是:它應該對當前的應用程序成爲可能版本來處理具有附加標籤的XML文件,簡單地忽略它。但是,如上所述,該應用程序對XSD有很強的驗證。也許有另一種方法來做到這一點?

+0

如果應用程序位於不同的名稱空間中,應用程序如何查看該新項目?我相信如果沒有架構修改,這是不可能的。 –

+0

@AlexeyR,命名空間只是一個(不幸的)例子。實際上,我需要一種方法,使標籤對XSD驗證完全透明,而不會明確允許* undefined *標籤。恐怕似乎是不可能的。 – dymanoid

回答

0

是的,沒有。如果原始模式有一個特殊的標籤,有一種方法可以實現這一點。

如果你事先知道文件可能有額外的元素,但你不提前知道這些元素,那麼模式可以以向前兼容的方式使用xs:any標籤設計,就像這樣:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    targetNamespace="http://my-custom-ns.com"> 
    <xs:element name="item"> 
     <xs:complexType> 
      <xs:sequence> 
       <xs:element name="active" type="xs:boolean"/> 
       <xs:element name="value" type="xs:string"/> 
       <xs:any namespace="##other" processContents="lax" minOccurs="0"/> 
      </xs:sequence> 
     </xs:complexType> 
    </xs:element> 
</xs:schema> 

這份文件是針對上述模式是有效的:

<my:item xmlns:my="http://my-custom-ns.com" xmlns:new="http://new-ns.com"> 
    <active>true</active> 
    <value>foo</value> 
</my:item> 

還有這樣一條:

<my:item xmlns:my="http://my-custom-ns.com" xmlns:new="http://new-ns.com"> 
    <active>true</active> 
    <value>foo</value> 
    <new:tag>bar</new:tag> 
</my:item> 

可以通過更改namespaceprocessContents屬性的值來調整xs:any的行爲。

但是,如果模式已經完成,並且超出了您的控制範圍,那麼額外的元素只有在原始設計者允許的情況下才會出現。

一個例子是... XML Schema本身。 XML Schema元素可能包含外部名稱空間中的任意屬性(幾種標準是以這種方式構建在XML Schema上的),這是因爲Schema的XML Schema明確允許其他名稱空間中的屬性。

+0

是的,我想過使用'xs:any'模式元素。但不幸的是,該模式已經在目標機器上,並且不升級應用程序版本就無法更改(由於特殊原因這是不可能的)。顯然,原始的模式設計者不允許使用額外的元素...... – dymanoid

0

另一個答案是重構XML實例。 XML Schema允許在更大的實例中嵌套經過模式驗證的XML(無需修改)。

<new:wrapper xmlns:my="http://my-custom-ns.com" xmlns:new="http://new-ns.com"> 
    <my:item> 
    <active>true</active> 
    <value>foo</value> 
    </my:item> 
    <new:tag>bar</new:tag> 
</new:wrapper> 

這可以通過導入前者和引用元素my:item的新模式來實現。

只要嵌套XML嚴格驗證它,前面的模式不需要任何修改。

+0

那麼,如果我可以將新模式提供給應用程序用戶,那將是可能的。但不幸的是,由於特殊原因,應用程序版本無法升級,所以我堅持使用舊版本。 – dymanoid

相關問題