我搜索过,没有发现任何解决此问题的问题。
我正在尝试针对架构验证各种XML,并且 它似乎正在验证所有格式良好的XML,而不仅仅是验证符合架构的XML 。我发布了我正在使用的代码,Schema,一个有效的XML示例和一个无效的XML示例。
我一直在努力解决这个问题。在大多数情况下,我处于黑暗中。我必须学习如何编写XSD,编写XSD,然后学习如何在C#中解析XML。我以前从未做过的。我已经使用了很多教程和微软网站来提出以下内容。我认为这应该有用,但事实并非如此。
我做错了什么?
private bool ValidateXmlAgainstSchema(string sourceXml, string schemaUri)
{
bool validated = false;
try
{
// REF:
// This should create a SCHEMA-VALIDATING XMLREADER
// http://msdn.microsoft.com/en-us/library/w5aahf2a(v=vs.110).aspx
XmlReaderSettings xmlSettings = new XmlReaderSettings();
xmlSettings.Schemas.Add("MySchema.xsd", schemaUri);
xmlSettings.ValidationType = ValidationType.Schema;
xmlSettings.ValidationFlags = XmlSchemaValidationFlags.None;
XmlReader xmlReader = XmlReader.Create(new StringReader(sourceXml), xmlSettings);
// parse the input (not sure this is needed)
while (xmlReader.Read()) ;
xmlDoc = new XmlDocument();
xmlDoc.Load(xmlReader);
validated = true;
}
catch (XmlException e)
{
// load or parse error in the XML
validated = false;
}
catch (XmlSchemaValidationException e)
{
// Validation failure in XML
validated = false;
}
catch (Exception e)
{
validated = false;
}
return validated;
}
XSD /架构。目的是接受包含Incident或PersonOfInterest的XML。
<?xml version="1.0" encoding="utf-8"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="MySchema.xsd"
xmlns="MySchema.xsd"
elementFormDefault="qualified"
>
<xs:element name="Incident" type="IncidentType"/>
<xs:element name="PersonOfInterest" type="PersonOfInterestType"/>
<xs:complexType name="IncidentType">
<xs:sequence>
<xs:element name="Description" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="PersonOfInterest" type="PersonOfInterestType" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="PersonOfInterestType">
<xs:sequence>
<xs:element name="Name" type="xs:string" minOccurs="1" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
以下是有效 XML
的示例<?xml version="1.0" encoding="utf-8" ?>
<Incident
xmlns="MySchema.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3schools.com MySchema.xsd"
>
<Description>something happened</Description>
<PersonOfInterest>
<Name>Joe</Name>
</PersonOfInterest>
<PersonOfInterest>
<Name>Sue</Name>
</PersonOfInterest>
</Incident>
这是格式良好的无效 XML的示例,它应该抛出异常(我想),但是当我尝试它时,代码返回true,表明它对模式有效。< / p>
<ghost>Boo</ghost>
答案 0 :(得分:3)
您的<ghost>Boo</ghost>
验证的原因是解析器找不到与xml匹配的任何模式。如果没有模式,则解析器假定有效性,前提是xml格式正确。我知道这是违反直觉的,并且可能会因解析器实现而有所不同。
尽管如此,您的代码存在一些问题:
两个根元素
这在xsd中是一个很大的禁忌 - 你只能拥有一个根元素。一些解析器实际上会抛出异常,其他解析器会容忍它,但只会使用第一个根元素(在您的情况下为 Incident )进行任何后续验证。
使用schemaLocation属性
这应该取值(namespace) (URI)
,其中命名空间是架构的targetNamespace,URI是架构的位置。在您的情况下,您似乎使用模式文件名作为目标名称空间。另外,查看代码时,您正在将模式加载到xml阅读器中,因此根本不需要schemaLocation属性。这是一个可选属性,一些解析器完全忽略它。
我建议进行以下更改:
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://MyMoreMeaningfulNamespace"
xmlns="http://MyMoreMeaningfulNamespace"
elementFormDefault="qualified"
>
<xs:element name="Root">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="Incident" type="IncidentType"/>
<xs:element maxOccurs="unbounded" name="PersonOfInterest" type="PersonOfInterestType"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="IncidentType">
<xs:sequence>
<xs:element name="Description" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="PersonOfInterest" type="PersonOfInterestType" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="PersonOfInterestType">
<xs:sequence>
<xs:element name="Name" type="xs:string" minOccurs="1" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
验证此实例
<Root xmlns="http://MyMoreMeaningfulNamespace">
<Incident>
<Description>something happened</Description>
<PersonOfInterest>
<Name>Joe</Name>
</PersonOfInterest>
<PersonOfInterest>
<Name>Sue</Name>
</PersonOfInterest>
</Incident>
<Incident>
...
</Incident>
<PersonOfInterest>
<Name>Manny</Name>
</PersonOfInterest>
<PersonOfInterest>
...
</PersonOfInterest>
</Root>