短篇小说:
我想在代码中使用 XSD 架构验证 XSD 文件(所有 XSD 本身都是 XML),并获得与 Visual Studio 在其(xml 作为文本)编辑器中打开相同 XSD 文件时显示的相同警告或错误。
Visual Studio 在其 xml 编辑器中显示警告(见下文)。
我的问题是,在代码中完成的验证是 100% 成功的。没有警告,什么都没有。我错过了什么?
长篇大论:
XSD 文件根据定义是一个 XML 文件,因此我正在使用针对 W3C xsd 模式的 XML 验证来验证我的自定义 XSD。
这是要验证的 XSD 和 VS 2010 显示的警告:(
单击 img 放大)
为了避免你眯眼,这里有一些警告:
通配符“##any”允许元素“Com.Example.Config:permissionConfig”,并导致内容模型变得不明确。必须形成一个内容模型,以便[... tl;dr]
这是我的自定义 XSD:
<?xml version="1.0" encoding="utf-8" ?>
<xs:schema
xmlns:tns="Com.Example.Config"
elementFormDefault="qualified"
targetNamespace="Com.Example.Config"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="Com.Example.Config.PermissionConfigCT" />
<xs:complexType name="Com.Example.Config.PermissionsCT">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="permissionConfig" type="tns:Com.Example.Config.PermissionConfigCT" />
<!-- next line triggers the warning -->
<xs:any minOccurs="0" processContents="lax" />
</xs:sequence>
</xs:complexType>
</xs:schema>
检查 VS 用于验证的模式(从菜单 XML -> 模式)显示它正在使用:
xsdschema.xsd
(FWIW,它源自W3C 的 XSD 原始模式,没有DTD 部分)xml.xsd
(在上一个 xsd 中引用,由一个 relativeinclude
)
这两个文件都驻留在(在我的机器上)这里:
C:\Program Files (x86)\Microsoft Visual Studio 10.0\xml\Schemas
我将它们都复制到与可执行文件相同的目录中,以便于参考。
为了完整起见,以下是xsdschema.xsd
定义其命名空间的方式:
<xs:schema
targetNamespace="http://www.w3.org/2001/XMLSchema"
blockDefault="#all"
elementFormDefault="qualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xml:lang="EN" version="1.0"
xmlns:vs="http://schemas.microsoft.com/Visual-Studio-Intellisense">
<xs:import namespace="http://www.w3.org/XML/1998/namespace"/>
<xs:complexType name="openAttrs">
[...]
...所以我继续编写了一些快速验证代码,使用与 VS 相同的 XSD。这是代码:
var configXsdPath = "XMLFile1.xml";
//that's my custom XSD file, don't let the extension fool you
var xmlSchemaForXsdPath = "xsdschema.xsd";
var settings = new XmlReaderSettings
{
ValidationType = ValidationType.Schema,
ValidationFlags = XmlSchemaValidationFlags.ReportValidationWarnings
| XmlSchemaValidationFlags.ProcessSchemaLocation
| XmlSchemaValidationFlags.ProcessIdentityConstraints
};
using (var tr = XmlReader.Create(xmlSchemaForXsdPath))
{
settings.Schemas.Add(XmlSchema.Read(tr, (i_sender, i_args)
=> {throw new InvalidOperationException(
"The validating XSD is itself invalid");} ));
}
settings.ValidationEventHandler += (i_sender, i_args)
=> { throw new Exception(i_args.Message); };
var reader = XmlReader.Create(configXsdPath, settings);
while (reader.Read())
//parse it all
{ }
...并且没有任何异常弹出...
更新接下来我尝试提供完全无效的 XML:我在自定义 XSD 中的某处添加了这个元素:
<aaa!></aaa>
并且代码给出了预期的错误*:
命名空间“ http://www.w3.org/2001/XMLSchema ”中的元素“模式”具有无效的子元素“aaa”。预期的可能元素列表:名称空间“ http://www.w3.org/2001/XMLSchema ”中的“simpleType、complexType、组、attributeGroup、元素、属性、符号、注释” 。
--
- 我曾简要说明过添加无效 XML 不会产生任何错误。那是PEBKAC的一个例子。