2012-10-31 113 views
2

我有下面的XML:使用XSD驗證XML元素

<?xml version="1.0" encoding="utf-8"?> 
<MainElement> 
    <id>1</id> 
    <name>John</name> 
    <custom> 
     <age>43</age> 
     <sex>male</sex> 
    </custom> 
</MainElement> 

而另一個XML文件:

<?xml version="1.0" encoding="utf-8"?> 
<MainElement> 
    <id>2</id> 
    <name>Dave</name> 
    <custom> 
     <age>51</age> 
     <county>England</country> 
     <city>London</city> 
    </custom> 
</MainElement> 

兩個XML文件的主要結構是同一只<custom>元素具有不同實現。我已經有了一個XSD文件來檢查「id」和「name」元素,其中<custom>元素的類型爲xs:anyType。是否可以創建另一個XSD文件,該文件只驗證<custom>元素而不查看所有其他存在的元素?

+0

你必須回答的第一件事是如何要弄清楚你應該得到哪個'custom'元素。如果您打算使用相同的標籤但使用不同的內容模型,則無法在XSD 1.0中執行此操作,而無需自定義預處理XML並動態加載相應的XSD(稱爲懸空定義),或者使用附加到自定義元素的xsi:type屬性。如果通過「自定義」元素表示任何命名元素,事情會變得更容易或更復雜,這取決於你想要的約束。如果你可以把更多的細節... –

+0

自定義元素將始終具有名稱'自定義',是一個可選元素。例如,有三個客戶會將XML文件發送給我,根據客戶的需要,我需要使用相應的XSD文件來驗證'custom'元素中的所有子元素。對於所有三個客戶,我將使用相同的XSD來驗證xml文件的其餘部分,如'id'和'name'元素。任何想法,如果這可以完成與XSD的唯一或我需要使用其他技術? – JustRonald

回答

0

我會向兩位顧客說明。第一個XSD是應該捕獲所有通用部分的基礎部分,除了我們引用但未定義的custom之外;我們把它留下來「搖晃」。

下面是common.xsd:

<?xml version="1.0" encoding="utf-8"?> 
<!--XML Schema generated by QTAssistant/XML Schema Refactoring (XSR) Module (http://www.paschidev.com)--> 
<xsd:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <xsd:element name="MainElement"> 
    <xsd:complexType> 
     <xsd:sequence> 
     <xsd:element name="id" type="xsd:unsignedByte" /> 
     <xsd:element name="name" type="xsd:string" /> 
     <xsd:element ref="custom"/> 
     </xsd:sequence> 
    </xsd:complexType> 
    </xsd:element> 
</xsd:schema> 

然後我們開始定義一個XSD每個custom。對於第一個XML(定製1.xsd):

<?xml version="1.0" encoding="utf-8"?> 
<!--XML Schema generated by QTAssistant/XML Schema Refactoring (XSR) Module (http://www.paschidev.com)--> 
<xsd:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <xsd:element name="custom"> 
     <xsd:complexType> 
      <xsd:sequence> 
       <xsd:element name="age" type="xsd:unsignedShort"/> 
       <xsd:element name="sex" type="xsd:string"/> 
      </xsd:sequence> 
     </xsd:complexType> 
    </xsd:element> 
</xsd:schema> 

而對於第二個,定製2.xsd:

<?xml version="1.0" encoding="utf-8"?> 
<!--XML Schema generated by QTAssistant/XML Schema Refactoring (XSR) Module (http://www.paschidev.com)--> 
<xsd:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <xsd:element name="custom"> 
     <xsd:complexType> 
      <xsd:sequence> 
       <xsd:element name="age" type="xsd:unsignedShort"/> 
       <xsd:element name="country" type="xsd:string"/> 
       <xsd:element name="city" type="xsd:string"/> 
      </xsd:sequence> 
     </xsd:complexType> 
    </xsd:element> 
</xsd:schema> 

那麼你必須要爲每個客戶創建一個模式集適當地裝載的XSD:第一組將包括公共+定製-1,然後共同+定製-2等

這是我將如何使用「可視化」這些組QTAssistant:

enter image description here

當然,Common本身無效。

Error occurred while loading [file:///.../validate-xml-element-with-xsd-2.xsd], line 9 position 10. 
The 'custom' element is not declared. 

然而,對方的收集是有效的,因爲在一組額外的XSD使進入活動範圍缺失的定義。現在您可以驗證每個供應商的XML及其關聯的集合。您保持供應商通用定義的完整性,因爲您確實共享了一個共同的XSD,並且您在XSD 1.0中使用了懸而未決的定義可以避開「限制」。我認爲這不是一個限制;這可能是一種「不太優雅」的方法......

從處理角度來看,您會承擔與您擁有的供應商一樣多次編譯和加載常見XSD(s)的開銷。

如果這成爲一種負擔,您也可以使用另一種策略,一旦預處理您的XML返回回報。您可以將custom定義爲anyType,甚至將其替換爲xsd:any。一旦驗證了常用的功能,您就可以提取節點(XSLT或DOM API或DOM節點閱讀器之上的驗證閱讀器等),並使用適當的XSD獨立驗證它。

後面方法的優點是您不會有任何XSD方面的開銷。當然,交易可能會增加處理的佔地面積。

XSD 1.1,XSD 1.0 + Schematron,RelaxNG是涉及另一種模式語言的解決方案,它們各有優缺點。我認爲上面應該至少可以幫助你理解你的一些選擇......

0

有了XSD,你不能用字面意思去任何!

所以你需要聲明所有來作爲XML的一部分。在這種或那種方式等..

我給豎起大拇指您使用導入的方法/包括..這是一個乾淨,並允許進一步擴展的要求..但你仍然應該知道的任何元素的可能的名稱..

雖然它不是必需的,你會intested知道使用Sequencechoice的另一種方法,只有達到您的要求,ONE XSD

這裏是代碼,這既證明了XML1和XML2:

<?xml version="1.0" encoding="utf-8"?> 
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:element name="MainElement"> 
    <xs:complexType> 
     <xs:sequence> 
     <xs:element name="id" type="xs:unsignedByte" /> 
     <xs:element name="name" type="xs:string" /> 
     <xs:element name="custom"> 
      <xs:complexType> 
      <xs:sequence> 
       <xs:choice> 
       <xs:element name="age" type="xs:unsignedByte" /> 
       </xs:choice> 
       <xs:choice> 
       <xs:sequence> 
        <xs:element name="sex" type="xs:string" /> 
       </xs:sequence> 
       <xs:sequence> 
        <xs:element name="country" type="xs:string"/> 
        <xs:element name="city" type="xs:string"/> 
       </xs:sequence> 
       </xs:choice> 
      </xs:sequence> 
      </xs:complexType> 
     </xs:element> 
     </xs:sequence> 
    </xs:complexType> 
    </xs:element> 
</xs:schema> 

這可能不是現在對您有用,但可能在未來..