我知道StackOverflow中已多次询问此问题并尝试了解决这些问题的所有解决方案。但是,在我的情况下,我创建的模式仅在我尝试使用包含Schema中存在的元素的XML进行验证时才有效。例如,我有一个XML包含<Users></Users>
元素,它存在于我的Schema中。
我想要的是使所有不符合我的Schema的XML无效。因此,如果XML确实具有<Users></Users>
,则验证应该抛出豁免。
以下是模式,我按文件和命名空间分隔:
用户架构
<?xml version="1.0" encoding="utf-8"?>
<xs:schema
targetNamespace="urn:company:schema:xsd:users"
elementFormDefault="qualified"
xmlns:cd="urn:company:schema:xsd:commondata"
xmlns:pfl="urn:company:schema:xsd:profile"
xmlns:usr="urn:company:schema:xsd:users"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
version="1.0">
<xs:import namespace="urn:company:schema:xsd:commondata" schemaLocation="company-common-data-schema-1.0.xsd" />
<xs:import namespace="urn:company:schema:xsd:profile" schemaLocation="company-profile-schema-1.0.xsd" />
<xs:annotation>
<xs:documentation>
Document Identifier: company-user-schema-1.0
Revision history:
V1.0
Initial Schema
</xs:documentation>
</xs:annotation>
<xs:element name="Users">
<xs:complexType>
<xs:sequence minOccurs="1" maxOccurs="unbounded">
<xs:element name="User" type="usr:UserType" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="UserType">
<xs:choice>
<xs:element name="EmailAddress" type="cd:EmailAddressType" />
<xs:element name="Active" type="xs:boolean" default="false" />
<xs:element name="Profile" type="pfl:ProfileType" minOccurs="0" />
</xs:choice>
</xs:complexType>
</xs:schema>
个人资料架构
<?xml version="1.0" encoding="utf-8"?>
<xs:schema
targetNamespace="urn:company:schema:xsd:profile"
elementFormDefault="qualified"
xmlns:pfl="urn:company:schema:xsd:profile"
xmlns:cd="urn:company:schema:xsd:commondata"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
version="1.0">
<xs:import namespace="urn:company:schema:xsd:commondata" schemaLocation="company-common-data-schema-1.0.xsd" />
<xs:annotation>
<xs:documentation>
Document Identifier: company-profile-schema-1.0
Revision history:
V1.0
Initial Standard
</xs:documentation>
</xs:annotation>
<xs:complexType name="ProfileType">
<xs:choice>
<xs:element name="FirstName" type="cd:NameType" />
<xs:element name="LastName" type="cd:NameType" />
<!-- remove other elements for brevity -->
</xs:choice>
</xs:complexType>
</xs:schema>
通用数据架构
<?xml version="1.0" encoding="utf-8"?>
<xs:schema
targetNamespace="urn:company:schema:xsd:commondata"
elementFormDefault="qualified"
xmlns:cdt="urn:company:schema:xsd:commondata"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
version="1.0">
<xs:annotation>
<xs:documentation>
Document Identifier: company-common-datatype-schema-1.0
Revision history:
V1.0
Initial Schema
</xs:documentation>
</xs:annotation>
<xs:simpleType name="EmailAddressType">
<xs:restriction base="xs:token">
<xs:maxLength value="254"/>
<xs:pattern value="[_\-a-zA-Z0-9'\.\+]+@[a-zA-Z0-9](\.?[\-a-zA-Z0-9]*[a-zA-Z0-9])*"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="NameType">
<xs:restriction base="xs:token">
<xs:maxLength value="100"/>
<xs:pattern value="[A-Za-z]+((\s)?((\'|\-|\.)?([A-Za-z])+))*" />
</xs:restriction>
</xs:simpleType>
</xs:schema>
注意:我正在将这些架构添加到资源中。
以下是我要验证的XML:
XML符合架构
<?xml version="1.0" encoding="utf-8"?>
<usr:Users>
<usr:User>
<usr:EmailAddress>john.doe@company.com</usr:EmailAddress>
<usr:Active>true</usr:Active>
<pfl:Profile>
<pfl:FirstName>John</pfl:FirstName>
<pfl:LastName>Doe</pfl:LastName>
</pfl:Profile>
</usr:User>
</usr:Users>
不符合架构的XML
<?xml version="1.0" encoding="utf-8"?>
<Foos>
<Foo>
<FooEmail>john.doe@company.com</FooEmail>
<FooActive>true</FooActive>
<FooProfile>
<FooFirstName>John</FooFirstName>
<FooLastName>Doe</FooLastName>
</FooProfile>
</Foo>
</Foos>
以下是我用来根据我的架构验证XML的代码:
// remove some of the codes for brevity
private static bool ValidateXml(string xmlSrc, XmlReaderSettings xrs, out IList<Tuple<object, Exception>> validationErrors)
{
var isValid = false;
var xmlReader = new object();
validationErrors = new List<Tuple<object, Exception>>();
try
{
using (var xtr = new XmlTextReader(xmlSrc))
using (var xr = XmlReader.Create(xtr, xrs))
{
while (xr.Read()) { }
xmlReader = xr;
}
isValid = true;
}
catch (Exception xdsEx)
{
validationErrors.Add(
new Tuple<object, Exception>(xmlReader, xdsEx));
}
return isValid;
}
private static XmlReaderSettings XmlSchemaReader(
IEnumerable<string> xmlSchemas,
out IList<Tuple<object, XmlSchemaException>> validationErrors)
{
var schemaCollection = new XmlSchemaSet();
var readerSettings = InitializeDefaultXmlReaderSettings();
var internalValidationErrors = new List<Tuple<object, XmlSchemaException>>();
foreach (var xmlSchema in xmlSchemas)
{
var iterationValidationErrors = new List<Tuple<object, XmlSchemaException>>();
var xsdReader = new StringReader(xmlSchema);
var schema = XmlSchema.Read(xsdReader,
(obj, eventArgs) => iterationValidationErrors.Add(
new Tuple<object, XmlSchemaException>(obj, eventArgs.Exception)));
readerSettings.Schemas.Add(schema);
internalValidationErrors.AddRange(iterationValidationErrors);
}
validationErrors = internalValidationErrors;
return readerSettings;
}
private static XmlReaderSettings InitializeDefaultXmlReaderSettings()
{
var readerSettings = new XmlReaderSettings();
readerSettings.ValidationType = ValidationType.Schema;
readerSettings.ValidationFlags |= XmlSchemaValidationFlags.AllowXmlAttributes;
readerSettings.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema;
readerSettings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
readerSettings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
return readerSettings;
}
我做错了什么?它正在使用第一个给定的XML示例。