【问题标题】:Difference in XSD Validation Errors between .net and other technologies.net 和其他技术之间 XSD 验证错误的差异
【发布时间】:2017-12-05 11:17:12
【问题描述】:

我有以下架构,用于在我的 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 中解决这个问题。但为什么会出现这种冲突?有没有办法改正。

【问题讨论】:

  • 应该是:XmlReader reader = XmlTextReader.Create(@"C:\visual studio 2015\Projects\WindowsFormsApplication1\SampleSchema.xsd");
  • 试过了,但这并不能解决问题
  • 这是一个非常愚蠢的错误。 5000 年无效。改为 2017 年。
  • 你认为到那时世界不会存在。这只是另一个无效的测试用例。 Michael Kay 的回答如下。
  • 我测试了您的代码,只需将 5000 更改为 2017 即可获得良好的结果。我收到一条输出消息“Success”。

标签: c# xml xsd


【解决方案1】:

Microsoft 的 XSD 处理器在使用正则表达式时不符合规范:通常它的正则表达式遵循 .NET 约定而不是 W3C 约定。

在这个特定示例中,问题在于字符 ^$ 在符合 XSD 正则表达式中是普通字符,而不是元字符。

【讨论】:

    【解决方案2】:

    这是我用来测试的代码:

    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;
                }
            }
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-02-12
      • 2011-03-23
      • 1970-01-01
      • 2014-05-27
      • 2016-10-28
      • 2011-09-02
      • 2012-07-14
      • 1970-01-01
      相关资源
      最近更新 更多