首页 > 解决方案 > XmlReader XSD 验证在带有 _ 的电子邮件正则表达式上失败

问题描述

我们的 XSD 中有以下正则表达式模式

    <xsd:restriction base='xsd:string'>
        <xsd:pattern value='([\w\-\.]+)@(([\w]+\.)+)([a-zA-Z]{2,15})'/>
    </xsd:restriction>

并针对它进行标准的 .Net XSD 验证。

        var validationErrors = new List<string>();

        // Set the validation settings.
        var settings = new XmlReaderSettings
        {
            ValidationType = ValidationType.Schema,
            Schemas = schemaSet
        };
        settings.ValidationEventHandler += (sender, e) => {
            validationErrors.Add(e.Message);
            };

        // Create the XmlReader object.
        var xmlString = AsString(input);


        var sr = new StringReader(xmlString);
        using (var reader = XmlReader.Create(sr, settings))
        {
            // Parse the file. 
            while (reader.Read()) ;
        }

        if (validationErrors.Any())
        {
            throw new ValidationException(validationErrors.ToArray());
        }

根据 xsd 验证将其声明为无效的正则表达式,电子邮件 your_name@mydomain.com 是有效的电子邮件。删除 _ 时,它可以工作。

我无法更改正则表达式模式,因为它是我们必须使用的外部 xsd。我无法找到此问题的根源或解决方法。

标签: c#regexxsd-validation

解决方案


这似乎是 XML 验证的已知问题

https://social.msdn.microsoft.com/Forums/en-US/5b7bb8e3-f9e9-42bd-a90a-a8498852abe9/whenever-there-is-underscore-82208221-in-the-email-address-the-xml-验证失败?forum=xmlandnetfx

通过捕获验证回调并执行手动正则表达式检查来解决它:

        XDocument doc = XDocument.Parse(xmlString);
        doc.Validate(schemaSet, (o, e) =>
        {
            var elem = o as XElement;
            if(elem != null && elem.Name.LocalName.Equals("email"))
            {
                var regex = @"([\w\-\.]+)@(([\w]+\.)+)([a-zA-Z]{2,15})";
                var match = Regex.Match(elem.Value, regex, RegexOptions.IgnoreCase);

                if (!match.Success)
                {
                    validationErrors.Add(e.Message);
                }
            }
            else
            {
                validationErrors.Add(e.Message);
            }
        });

        if (validationErrors.Any())
        {
            throw new ValidationException(validationErrors.ToArray());
        }

推荐阅读