模式验证 XML
Posted
技术标签:
【中文标题】模式验证 XML【英文标题】:schema validation XML 【发布时间】:2011-06-02 19:33:36 【问题描述】:我有一个 XSD 文件和一个 XML 文件,如何检查 XML 是否像 XSD 文件一样在正确的架构中?
我知道XmlDocument
类中有一个验证函数,但它需要一个事件处理程序
我只需要对或错。
附:我在 Visual Studio 2010 中工作。
【问题讨论】:
【参考方案1】:您可以使用 XmlReaderSettings 类和 Create 方法创建一个验证 XmlReader 实例。
private bool ValidateXml(string xmlFilePath, string schemaFilePath, string schemaNamespace, Type rootType)
XmlSerializer serializer = new XmlSerializer(rootType);
using (var fs = new StreamReader(xmlFilePath, Encoding.GetEncoding("iso-8859-1")))
object deserializedObject;
var xmlReaderSettings = new XmlReaderSettings();
if (File.Exists(schemaFilePath))
//select schema for validation
xmlReaderSettings.Schemas.Add(schemaNamespace, schemaPath);
xmlReaderSettings.ValidationType = ValidationType.Schema;
try
using (var xmlReader = XmlReader.Create(fs, xmlReaderSettings))
if (serializer.CanDeserialize(xmlReader))
return true;
//deserializedObject = serializer.Deserialize(xmlReader);
else
return false;
catch(Exception ex)
return false;
如果架构无效或无法反序列化xml,上述代码将抛出异常。 rootType 是等效类层次结构中根元素的类型。
示例:
架构位于:XML Schema Tutorial。将文件另存为D:\SampleSchema.xsd
。
运行xsd.exe
:
-
打开“开始菜单 > 所有程序 > Microsoft Visual Studio 2010 > Visual Studio 工具 > Visual Studio 2010 命令提示符”
在命令提示符下,键入:
xsd.exe /c /out:D:\ "D:\SampleSchema.xsd"
xsd选项:/out
选项指定输出目录,/c
指定生成类的工具
输出类层次结构存在于D:\SampleSchema.cs
生成的类层次结构看起来像这样,
//------------------------------------------------------------------------------
//
// This code was generated by a tool.
// Runtime Version:2.0.50727.4952
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
//------------------------------------------------------------------------------
using System.Xml.Serialization;
//
// This source code was auto-generated by xsd, Version=2.0.50727.3038.
//
///
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]
public partial class note
private string toField;
private string fromField;
private string headingField;
private string bodyField;
///
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string to
get
return this.toField;
set
this.toField = value;
///
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string from
get
return this.fromField;
set
this.fromField = value;
///
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string heading
get
return this.headingField;
set
this.headingField = value;
///
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string body
get
return this.bodyField;
set
this.bodyField = value;
将该类添加到 Visual Studio 项目中。
对于上面的 xsd 示例,根类是 note
。
调用方法,
bool isXmlValid = ValidateXml(@"D:\Sample.xml",
@"D:\SampleSchema.xsd",
@"http://www.w3.org/2001/XMLSchema",
typeof(note));
更多信息:
Validation Against XML Schema (XSD) with the XmlValidatingReader XML Schema Definition Tool (Xsd.exe)【讨论】:
这不会验证任何东西,因为没有设置 ValidationFlags。这只会反序列化 xml。 我应该输入什么作为 rootType? rootType 是从 xsd 文件创建的类模型的根元素的类型。例如,如果您创建一个类模型(使用 .NET 的 xsd.exe 工具),那么类型将为“Product”(对于@Steven 给出的示例 xsd)。 使用 .NET 的 xsd 工具创建类层次结构。例如,如果架构文件位于 'D:\testSchema.xsd',则工具用法应为 > xsd /c /out:D:\ "D:\testSchema.xsd"。这是一个命令行工具。欲了解更多信息:msdn.microsoft.com/en-us/library/x6c1kb0s%28v=VS.100%29.aspx 啊?与类型有什么联系?我想怎么写类型?【参考方案2】:你可以这样做。
public class XmlValidator
private bool _isValid = true;
public bool Validate(string xml)
_isValid = true;
// Set the validation settings as needed.
var settings = new XmlReaderSettings ValidationType = ValidationType.Schema ;
settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema;
settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
settings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
settings.ValidationEventHandler += ValidationCallBack;
var reader = XmlReader.Create(new StringReader(xml), settings);
while(reader.Read())
// process the content if needed
return _isValid;
private void ValidationCallBack(object sender, ValidationEventArgs e)
// check for severity as needed
if(e.Severity == XmlSeverityType.Error)
_isValid = false;
class Program
static void Main(string[] args)
var validator = new XmlValidator();
var result =
validator.Validate(@"<?xml version=""1.0""?>
<Product ProductID=""1"" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xsi:noNamespaceSchemaLocation=""schema.xsd"">
<ProductName>Chairs</ProductName>
</Product>");
架构。
<?xml version="1.0"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="Product">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="ProductName" type="xsd:string"/>
</xsd:sequence>
<xsd:attribute name="ProductID" use="required" type="xsd:int"/>
</xsd:complexType>
</xsd:element>
</xsd:schema>
【讨论】:
如何在不输入所有 xml 到函数调用的情况下做到这一点?以及“while”循环应该做什么?以及函数如何使用该方案? 您可以将路径传递给 Validate 函数并执行 'var reader = XmlReader.Create(path, settings);'而不是 'var reader = XmlReader.Create(new StringReader(xml), settings);' 好的。但是“while”循环应该做什么?以及函数如何使用该方案? while循环解析xml文档,并在这个过程中验证xml。 xml 包含对架构的引用:有一个非常简单的方法:
private void ValidationCallBack(object sender, ValidationEventArgs e)
throw new Exception();
public bool validate(string sxml)
try
XmlDocument xmld=new XmlDocument ();
xmld.LoadXml(sxml);
xmld.Schemas.Add(null,@"c:\the file location");
xmld.validate(ValidationCallBack);
return true;
catch
return false;
P.S : 我不是在 VS 中写的,所以可能会有不区分大小写的单词,但这段代码有效!
【讨论】:
谢谢,这正是我所需要的! 与其他解决方案相比非常简单,谢谢!以上是关于模式验证 XML的主要内容,如果未能解决你的问题,请参考以下文章