簡體   English   中英

針對Xsd驗證具有混雜子元素的Xml

[英]Validate an Xml with promiscuous child elements against 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>

如您所見,Task元素具有相同類型的子元素,這些子元素不會像GoTo元素那樣一個接一個地放置。 我使用了Microsoft Visual Studio命令提示符(2010)中的xsd.exe來基於上面的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文件,包括本示例中的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);    
}

我的問題是,我總是收到以下消息的驗證錯誤:

驗證錯誤:元素“任務”具有無效的子元素“ GoTo”。 可能的元素列表:“旋轉,SoundRecord,SoundPlayback”。

您是否知道我可以根據自己的架構驗證XML文件的方式,該方式只會檢查是否存在正確的元素類型,但不關心順序? 還是您知道我是否可以更改架構,以便XML文件通過驗證? 還是我的XML形式是一種不好的做法,並且它無法通過模式驗證? :)

我真的很感謝您的幫助。 謝謝

我們可以將xs:sequence替換為其中xs:sequence,該xs:sequence要求值必須以特定順序排列,並且可以不受限制地使用xs:choice來實現所需的結果。

嘗試這個。 注意我已經用<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>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM