[英]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.