.net 在C#中验证XSD,就像它是一个XML:donds';不要给出预期的警告
短篇小说: 我希望使用XSD模式在代码中验证XSD文件(所有XSD本身都是xml),并获得Visual Studio在其(xml为文本)编辑器中打开同一XSD文件时显示的相同警告或错误 VisualStudio在其xml编辑器中显示一条警告(请参见下文) 我的问题是,在代码中完成的验证获得了100%的成功。没有警告,什么也没有。我错过了什么 长话短说: XSD文件根据定义是一个XML文件,因此我使用W3CXSD模式的XML验证来验证我的自定义XSD 下面是要验证的XSD和一条警告,如VS 2010所示:.net 在C#中验证XSD,就像它是一个XML:donds';不要给出预期的警告,.net,xml,visual-studio,xsd,xsd-validation,.net,Xml,Visual Studio,Xsd,Xsd Validation,短篇小说: 我希望使用XSD模式在代码中验证XSD文件(所有XSD本身都是xml),并获得Visual Studio在其(xml为文本)编辑器中打开同一XSD文件时显示的相同警告或错误 VisualStudio在其xml编辑器中显示一条警告(请参见下文) 我的问题是,在代码中完成的验证获得了100%的成功。没有警告,什么也没有。我错过了什么 长话短说: XSD文件根据定义是一个XML文件,因此我使用W3CXSD模式的XML验证来验证我的自定义XSD 下面是要验证的XSD和一条警告,如VS 201
(单击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>
<aaa!></aaa>
…所以我继续写了一些快速验证代码,使用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中的某个位置添加了此元素:
<?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>
<aaa!></aaa>
”具有无效的子元素“aaa”。可能元素的列表应为:命名空间“”中的“simpleType、complexType、group、attributeGroup、element、attribute、notation、annotation”
--
- 我在某个时候简要地说,添加无效的XML不会产生任何错误。那是一个很好的例子
简单地说,您试图通过根据W3C XSD模式验证XSD来实现的目标—您的验证程序在下一行触发警告
—永远不会起作用。这就是所谓的XSD语言无法描述的东西。问题是,这只是开始;最终使用的XSD特性越多,建议的验证就越不可靠
如果您真的要验证XSD,至少在.NET上,请使用。要打开和关闭UPA检查,请说明如何操作。简单地说,您试图实现的目标—您的验证器在下一行触发警告
—根据W3C XSD模式验证您的XSD
永远不会起作用。这就是所谓的XSD语言无法描述的东西。问题是,这只是开始;最终使用的XSD特性越多,建议的验证就越不可靠
如果您真的要验证XSD,至少在.NET上,请使用。要打开和关闭UPA检查,请选择如何操作。Petru Gardea的伟大见解:将XSD视为XML仅在验证时有效,因此应将其视为XSD(或者除此之外)
就这么简单:
var schemas = new XmlSchemaSet();
using (var tr = XmlReader.Create(xsdPath))
{
schemas.Add(null, tr);
//null means 'use the target namespace specified in the XSD'
}
//schemas.CompilationSettings.EnableUpaCheck = true; //it's true by default
schemas.Compile();
运行上述代码将抛出XmlSchemaException
,并使用Visual Studio给出的确切描述:
System.Xml.Schema.XmlSchemaException:通配符“##any”允许元素
'Com.Example.Config:permissionConfig',并导致
模型变得模棱两可。内容模型的形成必须确保
在验证元素信息项序列期间
直接、间接或含蓄地包含在其中的粒子
依次尝试验证序列中的每个项目的
唯一确定,无需检查的内容或属性
该项目,并且没有关于中项目的任何信息
序列的剩余部分
Petru Gardea的伟大洞见:将XSD当作XML只在验证时有效,所以将其当作XSD来代替(或除此之外)
就这么简单:
var schemas = new XmlSchemaSet();
using (var tr = XmlReader.Create(xsdPath))
{
schemas.Add(null, tr);
//null means 'use the target namespace specified in the XSD'
}
//schemas.CompilationSettings.EnableUpaCheck = true; //it's true by default
schemas.Compile();
运行上述代码将抛出XmlSchemaException
,并使用Visual Studio给出的确切描述:
System.Xml.Schema.XmlSchemaException:通配符“##any”允许元素
'Com.Example.Config:permissionConfig',并导致
模型变得模棱两可。内容模型的形成必须确保
在验证元素信息项序列期间
直接、间接或含蓄地包含在其中的粒子
依次尝试验证序列中的每个项目的
唯一确定,无需检查的内容或属性
该项目,并且没有关于中项目的任何信息
序列的剩余部分
使用XmlReader有什么具体原因吗?为什么不使用XmlDocument或XDocument呢?虽然我更喜欢使用Linq而不是Xml来阅读Xmls(XDoc等人),但在我看来,XmlReader在验证方面提供了更大的灵活性。另外,我还发现了更多使用XmlReader的XSD验证示例。您确定阅读了您认为应该阅读的文件吗?您使用硬编码的相对路径,因此您的文件应该位于,例如bin\Debug
或bin\Release
,具体取决于您的设置。为了保持理智,您可以尝试指定完全限定的路径。@Christian实际的厨房水槽管道有点长,也比较复杂,但这与此处无关。当我写下无效XML不会给出验证错误(我将无效XML添加到错误的文件中)时,我确实是出于您的原因弄糟了它,但我修复了它。您使用XmlReader有具体原因吗?为什么不使用XmlDocument或XDocument呢?虽然我更喜欢使用Linq而不是Xml来阅读Xmls(XDoc等人),但在我看来,XmlReader在验证方面提供了更大的灵活性。另外,我还发现了更多使用XmlReader的XSD验证示例。您确定阅读了您认为应该阅读的文件吗?您使用硬编码的相对路径,因此您的文件应该位于,例如bin\Debug
或bin\Release
,具体取决于您的设置。为了保持理智,您可以尝试指定