我使用以下架构来验证c#应用程序中的XML。 以下代码是我正在做的事情的例子。但我发现,与其他技术的验证相比,验证存在差异。我不确定它是否与正则表达式有关。
<xsd:schema targetNamespace="http://tempuri.org/XMLSchema.xsd"
elementFormDefault="qualified"
xmlns="http://tempuri.org/XMLSchema.xsd"
xmlns:mstns="http://tempuri.org/XMLSchema.xsd"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
>
<xsd:simpleType name="DateCCYYType">
<xsd:annotation>
<xsd:documentation>A type that is used for any century/year combination field.</xsd:documentation>
</xsd:annotation>
<xsd:restriction base="xsd:string">
<xsd:maxLength value="4"/>
<xsd:pattern value="(^$|[1-2][0-9][0-9][0-9])"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="PersonalDetails">
<xsd:sequence>
<xsd:element name="yearJoined" type="mstns:DateCCYYType"></xsd:element>
<xsd:element name="yearReleased" type="mstns:DateCCYYType"></xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="PersonalDetails" type="mstns:PersonalDetails"></xsd:element>
</xsd:schema>
类文件如下
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
/*textBox1 Contains the xml text
<urn:PersonalDetails xmlns:urn="http://tempuri.org/XMLSchema.xsd">
<urn:yearJoined></urn:yearJoined>
<urn:yearReleased>5000</urn:yearReleased>
</urn:PersonalDetails>
*/
StringReader reader = new StringReader(textBox1.Text);
XmlTextReader xmlReader = new XmlTextReader(@"C:\visual studio 2015\Projects\WindowsFormsApplication1\SampleSchema.xsd");
Exception xsdException = new Exception();
try
{
bool isValid = IsXmlValidForSchema(reader, xmlReader, ref xsdException);
if (isValid)
{
MessageBox.Show("Success");
}
}
catch(Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
public static void ValidateXml(
StringReader srXML,
XmlTextReader xtrSchema)
{
XmlSchemaSet xssValidate = null;
try
{
xssValidate = new XmlSchemaSet();
xssValidate.Add(null, xtrSchema);
xssValidate.Compile();
XPathDocument xpdValidate = new XPathDocument(srXML);
XPathNavigator editor = xpdValidate.CreateNavigator();
if (!editor.CheckValidity(xssValidate, ValidateEventHandler))
{
throw new System.Xml.Schema.XmlSchemaValidationException();
}
}
finally
{
if (xssValidate != null) xssValidate = null;
}
}
public static bool IsXmlValidForSchema(
StringReader xmlReader,
XmlTextReader schemaReader, ref Exception xsdException)
{
bool result = true;
try
{
ValidateXml(xmlReader, schemaReader);
}
catch (XmlSchemaValidationException ex)
{
xsdException = ex;
result = false;
}
return result;
}
private static void ValidateEventHandler(object sender, ValidationEventArgs e)
{
if (e.Severity == XmlSeverityType.Error || e.Severity == XmlSeverityType.Warning)
{
XmlSchemaException schemaException = new XmlSchemaException(e.Message, e.Exception);
throw schemaException;
}
}
}
如果在注释块中使用xml,它会验证正常,并且不会因yearJoined的空白而抛出错误。但是,如果我使用其他验证器(如XMLSPY或任何在线验证器)对此进行验证,则会将这些验证器显示为错误。
我可以使用minLength
在.Net中修复此问题。但为什么会发生冲突呢?有没有办法纠正它。
答案 0 :(得分:0)
Microsoft的XSD处理器在使用正则表达式方面不符合要求:通常它的正则表达式遵循.NET约定而不是W3C约定。
在这个特定示例中,问题是字符^
和$
,它们是符合XSD正则表达式的普通字符,而不是元字符。
答案 1 :(得分:0)
以下是我用来测试的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Schema;
using System.Xml.XPath;
using System.IO;
namespace ConsoleApplication16
{
class Program
{
const string SCHEMA_FILENAME = @"c:\temp\test1.xml";
static void Main(string[] args)
{
//textBox1 Contains the xml text
string xml = "<urn:PersonalDetails xmlns:urn=\"http://tempuri.org/XMLSchema.xsd\">" +
"<urn:yearJoined></urn:yearJoined>" +
"<urn:yearReleased>2017</urn:yearReleased>" +
"</urn:PersonalDetails>";
StringReader reader = new StringReader(xml);
XmlTextReader xmlReader = new XmlTextReader(SCHEMA_FILENAME);
Exception xsdException = new Exception();
try
{
bool isValid = IsXmlValidForSchema(reader, xmlReader, ref xsdException);
if (isValid)
{
Console.WriteLine("Success");
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
public static void ValidateXml(
StringReader srXML,
XmlTextReader xtrSchema)
{
XmlSchemaSet xssValidate = null;
try
{
xssValidate = new XmlSchemaSet();
xssValidate.Add(null, xtrSchema);
xssValidate.Compile();
XPathDocument xpdValidate = new XPathDocument(srXML);
XPathNavigator editor = xpdValidate.CreateNavigator();
if (!editor.CheckValidity(xssValidate, ValidateEventHandler))
{
throw new System.Xml.Schema.XmlSchemaValidationException();
}
}
finally
{
if (xssValidate != null) xssValidate = null;
}
}
public static bool IsXmlValidForSchema(
StringReader xmlReader,
XmlTextReader schemaReader, ref Exception xsdException)
{
bool result = true;
try
{
ValidateXml(xmlReader, schemaReader);
}
catch (XmlSchemaValidationException ex)
{
xsdException = ex;
result = false;
}
return result;
}
private static void ValidateEventHandler(object sender, ValidationEventArgs e)
{
if (e.Severity == XmlSeverityType.Error || e.Severity == XmlSeverityType.Warning)
{
XmlSchemaException schemaException = new XmlSchemaException(e.Message, e.Exception);
throw schemaException;
}
}
}
}