2009-05-31 126 views
3

我有以下的(errorous)XML:XSD驗證問題

<jobs> 
    <job> 
     <id>1</id> 
     <state><![CDATA[IL]]></state> 
    </job> 
    <job> 
     <id>2</id> 
    </job> 
</jobs> 

兩個ID,並reqired項目狀態節點。我寫了一個XSD吧:

<?xml version="1.0" encoding="utf-8"?> 
<xs:schema id="importvalidator" 
    elementFormDefault="qualified" 
    targetNamespace="http://foo.org/importvalidator.xsd" 
    xmlns="http://foo.org/importvalidator.xsd" 
    xmlns:mstns="http://foo.org/importvalidator.xsd" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:element name="jobs"> 
     <xs:complexType> 
      <xs:sequence> 
      <xs:element name="job" minOccurs="1" maxOccurs="unbounded"> 
       <xs:complexType> 
       <xs:all> 
        <xs:element name="id" type="xs:string" minOccurs="1"/> 
        <xs:element name="state" type="xs:string" minOccurs="1"/> 
       </xs:all> 
       </xs:complexType> 
      </xs:element> 
      </xs:sequence> 
     </xs:complexType> 
    </xs:element> 
</xs:schema> 

它仍然驗證作爲結構有效的XML。我在這裏錯過了什麼?

UPDATE1:我正在使用的代碼是C#:

 XmlSchemaSet schemas = new XmlSchemaSet(); 
     schemas.Add("http://foo.org/importvalidator.xsd", "validator.xsd"); 

     XDocument doc = XDocument.Load(fileName); 
     if (doc == null | doc.Root == null) 
     { 
      throw new ApplicationException("xml error: the referenced stream is not xml."); 
     } 

     doc.Validate(schemas, (o, e) => 
     { 
      throw new ApplicationException("xsd validation error: xml file has structural problems"); 
     }); 

回答

3

請格式化你的XML所以它更容易閱讀 - 這樣的:

<jobs> 
    <job> 
    <id>1</id> 
    <state><![CDATA[IL]]></state> 
    </job> 
    <job> 
    <id>2</id> 
    </job> 
</jobs> 

我想你沒有真正驗證它 - 命名空間意味着該XML不驗證,即使有「<state>」在第二個「<job>」。具體而言,XSD的目標命名空間爲「http://foo.org/importvalidator.xsd」,但XML沒有給出命名空間。

設置一個簡單的XSD和XML測試用例,你肯定知道會失敗 - 用它來追蹤你沒有驗證的原因。

此外,您的XSD缺少元素和模式的關閉標籤,所以它應該給一個錯誤 - 或者它只是一個誤貼:-)


您可以從模式中刪除的targetNamespace :

<xs:schema id="importvalidator" 
    elementFormDefault="qualified" 
    targetNamespace="http://foo.org/importvalidator.xsd ← DELETE THIS" 
    xmlns="http://foo.org/importvalidator.xsd" 
    xmlns:mstns="http://foo.org/importvalidator.xsd" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"> 

所以它看起來像這樣:

<xs:schema id="importvalidator" 
    elementFormDefault="qualified" 
    xmlns="http://foo.org/importvalidator.xsd" 
    xmlns:mstns="http://foo.org/importvalidator.xsd" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"> 

PS:誰知道是否/如何能高SO的降價源代碼的輕部分?

+2

@ 13ren:我修正了他的格式,所以關閉的標籤是可見的。你有正確的答案:由於命名空間而不能驗證。 – 2009-05-31 16:36:13

0

哪個解析器/語言是您使用?過去的情況是,如果您使用的是Java,則必須告訴Xerces解析器您需要XSD驗證。但是在檢查latest release文檔後,我發現驗證是現在內置的。所以這個版本看起來很重要。如果您是.NET開發人員,最好檢查一下它的設置。

只是好奇 - 爲什麼CDATA在你的例子中圍繞狀態?沒有必要,AFAIK。您甚至可以在XSD中嵌入限制,以確保您只能獲得有效的美國州代碼。

但首先要做的是讓模式驗證。

+0

@duffymo:感謝您的評論,1)它是C#中的.net項目。 2)我知道,但我不能修改Xml的結構,順便說一下,狀態碼驗證不在項目範圍內(尚未)。 – balint 2009-05-31 15:56:14

+0

非常歡迎balint。對不起,我沒有更多的幫助。我不會考慮刪除不必要的CDATA作爲修改結構,但也許我不知道所有的要求。如果狀態驗證變得重要,那麼考慮狀態驗證是很好的,但也許那一天不是今天。 – duffymo 2009-05-31 16:24:28

2

@ 13ren有正確的答案。如果節點不匹配任何模式,則不會發生錯誤。這只是一個警告。我可以看到警告下面的代碼:

private static void ValidateDocument(XmlSchemaSet schemas, string uri) 
{ 
    var settings = new XmlReaderSettings 
         { 
          Schemas = schemas, 
          ValidationFlags = 
           XmlSchemaValidationFlags. 
            ProcessIdentityConstraints | 
           XmlSchemaValidationFlags. 
            ReportValidationWarnings, 
          ValidationType = ValidationType.Schema 
         }; 
    settings.ValidationEventHandler += OnValidationEventHandler; 
    using (var validatingReader = XmlReader.Create(uri, settings)) 
    { 
     XDocument.Load(
      validatingReader, 
      LoadOptions.SetBaseUri | LoadOptions.SetLineInfo); 
    } 
    return; 
} 

這將產生以下:

警告:無法找到元素「工作」的架構信息。 警告:找不到元素'作業'的模式信息。 警告:找不到元素「id」的架構信息。 警告:找不到元素「狀態」的模式信息。 警告:找不到元素'作業'的模式信息。 警告:找不到元素「id」的架構信息。

改變你的XML並再次運行:

<?xml version="1.0" encoding="utf-8" ?> 
<jobs xmlns="http://foo.org/importvalidator.xsd"> 
    <job> 
    <id>1</id> 
    <state><![CDATA[IL]]></state> 
    </job> 
    <job> 
    <id>2</id> 
    </job> 
</jobs> 

產生預期中的錯誤:

錯誤:命名空間 'http://foo.org/importvalidator.xsd' 元素「的工作具有不完整的內容。預期的可能元素列表:名稱空間'http://foo.org/importvalidator.xsd'中的'狀態'。