2013-05-11 75 views
1

我有一個如下所示的XML文件。我用它來給一系列命令的機器人:使用Xsd中的混雜子元素驗證Xml

<Task StartPosition="100,100"> 
     <GoTo> 
     <X>100</X> 
     <Y>200</Y> 
     </GoTo> 
     <MoveForward> 
     <Distance>50</Distance><!--cm--> 
     </MoveForward> 
     <Rotate Direction="clockwise" Time="2"> 
     <Degrees>60</Degrees> 
     </Rotate> 
     <GoTo> 
     <X>200</X> 
     <Y>300</Y> 
     </GoTo> 
     <Rotate Direction="clockwise"> 
     <Degrees>120</Degrees> 
     </Rotate> 
     <SoundRecord> 
     <Time>5</Time> 
     </SoundRecord> 
     <SoundPlayback> 
     <Time>5</Time> 
     </SoundPlayback> 
    </Task> 

正如你可以看到任務元素有沒有被放在了一個又一個,像轉到元素相同類型的子元素。 我用XSD.EXE從Microsoft Visual Studio命令提示符(2010)基於上面的XML文件來生成這個架構:

<?xml version="1.0" encoding="utf-8"?> 
<xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> 
    <xs:element name="Task"> 
    <xs:complexType> 
     <xs:sequence> 
     <xs:element name="GoTo" minOccurs="0" maxOccurs="unbounded"> 
      <xs:complexType> 
      <xs:sequence> 
       <xs:element name="X" type="xs:string" minOccurs="0" /> 
       <xs:element name="Y" type="xs:string" minOccurs="0" /> 
      </xs:sequence> 
      </xs:complexType> 
     </xs:element> 
     <xs:element name="MoveForward" minOccurs="0" maxOccurs="unbounded"> 
      <xs:complexType> 
      <xs:sequence> 
       <xs:element name="Distance" type="xs:string" minOccurs="0" /> 
      </xs:sequence> 
      </xs:complexType> 
     </xs:element> 
     <xs:element name="Rotate" minOccurs="0" maxOccurs="unbounded"> 
      <xs:complexType> 
      <xs:sequence> 
       <xs:element name="Degrees" type="xs:string" minOccurs="0" msdata:Ordinal="0" /> 
      </xs:sequence> 
      <xs:attribute name="Direction" type="xs:string" /> 
      <xs:attribute name="Time" type="xs:string" /> 
      </xs:complexType> 
     </xs:element> 
     <xs:element name="SoundRecord" minOccurs="0" maxOccurs="unbounded"> 
      <xs:complexType> 
      <xs:sequence> 
       <xs:element name="Time" type="xs:string" minOccurs="0" /> 
      </xs:sequence> 
      </xs:complexType> 
     </xs:element> 
     <xs:element name="SoundPlayback" minOccurs="0" maxOccurs="unbounded"> 
      <xs:complexType> 
      <xs:sequence> 
       <xs:element name="Time" type="xs:string" minOccurs="0" /> 
      </xs:sequence> 
      </xs:complexType> 
     </xs:element> 
     </xs:sequence> 
     <xs:attribute name="StartPosition" type="xs:string" /> 
    </xs:complexType> 
    </xs:element> 
    <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true"> 
    <xs:complexType> 
     <xs:choice minOccurs="0" maxOccurs="unbounded"> 
     <xs:element ref="Task" /> 
     </xs:choice> 
    </xs:complexType> 
    </xs:element> 
</xs:schema> 

我驗證我的XML文件,包括一個在反對這個這個例子架構使用下面的代碼:

XmlReaderSettings settings = new XmlReaderSettings(); 
settings.ValidationType = ValidationType.Schema; 
settings.Schemas.Add(null, xsdFilePath); 
settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema; 
settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation; 
settings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings; 
settings.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack); 

// Create the XmlReader object. 
XmlReader reader = XmlReader.Create(xmlFilePath, settings); 

// Parse the file to validate it 
while (reader.Read()); 

\**************************************************\ 

private static void ValidationCallBack(object sender, ValidationEventArgs args) 
{ 
    if (args.Severity == XmlSeverityType.Warning) 
     throw new Exception("\tWarning: Matching schema not found. No validation  occurred." + args.Message); 
    else 
     throw new Exception("\tValidation error: " + args.Message);  
} 

我的問題是,我總是得到一個驗證錯誤,消息如下:

驗證錯誤:元素「任務」具有無效子元素「轉到」。預期可能的元素列表:'旋轉,SoundRecord,SoundPlayback'。

你知道一種方法,我可以根據我的模式驗證我的XML文件,只檢查是否存在正確的元素類型,但不關心順序? 或者你知道我是否可以改變某些模式以便XML文件通過驗證? 或者是我的XML的形式是一種不好的做法,它有沒有辦法通過模式的自我評估? :)

我真的很感激任何幫助。謝謝

回答

1

我們可以用一個無限制的xs:choice來替換xs:sequence,其中的值需要按照特定的順序,這個xs:choice可以達到所需的結果。

試試這個。注意我已將<xs:sequence>替換爲<xs:choice>。還要注意允許儘可能多的選擇的屬性。

<?xml version="1.0" encoding="utf-8"?> 
<xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> 
    <xs:element name="Task"> 
    <xs:complexType> 
     <xs:choice minOccurs="0" maxOccurs="unbounded"><!-- Here is the change --> 
     <xs:element name="GoTo" minOccurs="0" maxOccurs="unbounded"> 
      <xs:complexType> 
      <xs:sequence> 
       <xs:element name="X" type="xs:string" minOccurs="0" /> 
       <xs:element name="Y" type="xs:string" minOccurs="0" /> 
      </xs:sequence> 
      </xs:complexType> 
     </xs:element> 
     <xs:element name="MoveForward" minOccurs="0" maxOccurs="unbounded"> 
      <xs:complexType> 
      <xs:sequence> 
       <xs:element name="Distance" type="xs:string" minOccurs="0" /> 
      </xs:sequence> 
      </xs:complexType> 
     </xs:element> 
     <xs:element name="Rotate" minOccurs="0" maxOccurs="unbounded"> 
      <xs:complexType> 
      <xs:sequence> 
       <xs:element name="Degrees" type="xs:string" minOccurs="0" msdata:Ordinal="0" /> 
      </xs:sequence> 
      <xs:attribute name="Direction" type="xs:string" /> 
      <xs:attribute name="Time" type="xs:string" /> 
      </xs:complexType> 
     </xs:element> 
     <xs:element name="SoundRecord" minOccurs="0" maxOccurs="unbounded"> 
      <xs:complexType> 
      <xs:sequence> 
       <xs:element name="Time" type="xs:string" minOccurs="0" /> 
      </xs:sequence> 
      </xs:complexType> 
     </xs:element> 
     <xs:element name="SoundPlayback" minOccurs="0" maxOccurs="unbounded"> 
      <xs:complexType> 
      <xs:sequence> 
       <xs:element name="Time" type="xs:string" minOccurs="0" /> 
      </xs:sequence> 
      </xs:complexType> 
     </xs:element> 
     </xs:choice> 
     <xs:attribute name="StartPosition" type="xs:string" /> 
    </xs:complexType> 
    </xs:element> 
    <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true"> 
    <xs:complexType> 
     <xs:choice minOccurs="0" maxOccurs="unbounded"> 
     <xs:element ref="Task" /> 
     </xs:choice> 
    </xs:complexType> 
    </xs:element> 
</xs:schema> 
+0

非常感謝。我做了改變,我的xmls通過了驗證 – vicch 2013-05-11 13:46:28