C# - XML 架构验证器






4.90/5 (29投票s)
本文演示了一个 XML Schema 验证类的使用。
引言
你是否曾经在利用 Web Services、XML 和 Schema 的项目中工作过?那么你可能需要确保传递给 Web Service 的 XML 是否符合 Schema 的有效性。本文展示了如何使用 .NET 的 XmlValidatingReader
来使用 Schema 验证 XML。
使用代码
- 创建
XmlSchemaValidator
类。 - 创建 XML Schema。
- 创建一个 WebService 并添加
ValidateXML
方法。
注意:所有代码都可通过可下载的 zip 文件获得。
XmlSchemaValidator 类
XmlSchemaValidator
类包含一个重载的公共方法 ValidXmlDoc
。此方法允许调用者传递一个 XML 的 string
、一个 XmlDocument
或一个 XML 的 StringReader
。其他参数是用于验证 XML 的 Schema 的命名空间和 URI。该方法返回一个布尔值,如果 XML 有效则返回 true
,如果 XML 无效则返回 false
。还有一个公共的 string
"ValidationError
",其中包含验证错误。
using System;
using System.Xml;
using System.Xml.Schema;
using System.IO;
namespace YourNameSpace.GoesHere
{
/// <SUMMARY>
/// This class validates an xml string or xml document against an xml
/// schema.
/// It has public methods that return a boolean value depending on
/// the validation
/// of the xml.
/// </SUMMARY>
public class XmlSchemaValidator
{
private bool isValidXml = true;
private string validationError = "";
/// <SUMMARY>
/// Empty Constructor.
/// </SUMMARY>
public XmlSchemaValidator()
{
}
/// <SUMMARY>
/// Public get/set access to the validation error.
/// </SUMMARY>
public String ValidationError
{
get
{
return "<VALIDATIONERROR>" + this.validationError
+ "</VALIDATIONERROR>";
}
set
{
this.validationError = value;
}
}
/// <SUMMARY>
/// Public get access to the isValidXml attribute.
/// </SUMMARY>
public bool IsValidXml
{
get
{
return this.isValidXml;
}
}
/// <SUMMARY>
/// This method is invoked when the XML does not match
/// the XML Schema.
/// </SUMMARY>
/// <PARAM name="sender"></PARAM>
/// <PARAM name="args"></PARAM>
private void ValidationCallBack(object sender,
ValidationEventArgs args)
{
// The xml does not match the schema.
isValidXml = false;
this.ValidationError = args.Message;
}
/// <SUMMARY>
/// This method validates an xml string against an xml schema.
/// </SUMMARY>
/// <PARAM name="xml">XML string</PARAM>
/// <PARAM name="schemaNamespace">XML Schema Namespace</PARAM>
/// <PARAM name="schemaUri">XML Schema Uri</PARAM>
/// <RETURNS>bool</RETURNS>
public bool ValidXmlDoc(string xml,
string schemaNamespace, string schemaUri)
{
try
{
// Is the xml string valid?
if(xml == null || xml.Length < 1)
{
return false;
}
StringReader srXml = new StringReader(xml);
return ValidXmlDoc(srXml, schemaNamespace, schemaUri);
}
catch(Exception ex)
{
this.ValidationError = ex.Message;
return false;
}
}
/// <SUMMARY>
/// This method validates an xml document against an xml
/// schema.
public bool ValidXmlDoc(XmlDocument xml,
string schemaNamespace, string schemaUri)
{
try
{
// Is the xml object valid?
if(xml == null)
{
return false;
}
// Create a new string writer.
StringWriter sw = new StringWriter();
// Set the string writer as the text writer
// to write to.
XmlTextWriter xw = new XmlTextWriter(sw);
// Write to the text writer.
xml.WriteTo(xw);
// Get
string strXml = sw.ToString();
StringReader srXml = new StringReader(strXml);
return ValidXmlDoc(srXml, schemaNamespace, schemaUri);
}
catch(Exception ex)
{
this.ValidationError = ex.Message;
return false;
}
}
/// <SUMMARY>
/// This method validates an xml string against an xml schema.
/// </SUMMARY>
/// <PARAM name="xml">StringReader containing xml</PARAM>
/// <PARAM name="schemaNamespace">XML Schema Namespace</PARAM>
/// <PARAM name="schemaUri">XML Schema Uri</PARAM>
/// <RETURNS>bool</RETURNS>
public bool ValidXmlDoc(StringReader xml,
string schemaNamespace, string schemaUri)
{
// Continue?
if(xml == null || schemaNamespace == null || schemaUri == null)
{
return false;
}
isValidXml = true;
XmlValidatingReader vr;
XmlTextReader tr;
XmlSchemaCollection schemaCol = new XmlSchemaCollection();
schemaCol.Add(schemaNamespace, schemaUri);
try
{
// Read the xml.
tr = new XmlTextReader(xml);
// Create the validator.
vr = new XmlValidatingReader(tr);
// Set the validation tyep.
vr.ValidationType = ValidationType.Auto;
// Add the schema.
if(schemaCol != null)
{
vr.Schemas.Add(schemaCol);
}
// Set the validation event handler.
vr.ValidationEventHandler +=
new ValidationEventHandler(ValidationCallBack);
// Read the xml schema.
while(vr.Read())
{
}
vr.Close();
return isValidXml;
}
catch(Exception ex)
{
this.ValidationError = ex.Message;
return false;
}
finally
{
// Clean up...
vr = null;
tr = null;
}
}
}
}
XmlSchema 示例
以下代码是一个用于验证示例 XML 的示例 Schema 文件
<xs:schema id="XSDSchemaTest"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
attributeFormDefault="unqualified"
>
<xs:simpleType name="FamilyMemberType">
<xs:restriction base="xs:string">
<xs:enumeration value="384" />
<xs:enumeration value="385" />
<xs:enumeration value="386" />
<xs:enumeration value="" />
</xs:restriction>
</xs:simpleType>
<xs:element name="Answer">
<xs:complexType>
<xs:sequence>
<xs:element name="ShortDesc" type="FamilyMemberType" />
<xs:element name="AnswerValue" type="xs:int" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
XML 示例
根据 Schema 验证的示例 XML
<Answer>
<ShortDesc>385</ShortDesc>
<AnswerValue>1</AnswerValue>
</Answer>
WebService 示例
WebService 具有一个公共方法,用于验证 XML。此方法提供了一个示例,说明验证器对象可以使用的多种方式之一。请记住,ValidXmlDoc
方法有三个重载。
[WebMethod]
public string ValidateXml(string xml)
{
XmlSchemaValidator validator = new XmlSchemaValidator();
string retVal = "<VALIDXML>" +
validator.ValidXmlDoc(xml, "",
Server.MapPath("XSDSchemaTest.xsd")).ToString() +
"</VALIDXML>";
if(!validator.IsValidXml)
{
retVal = retVal + validator.ValidationError;
}
return retVal;
}