首页 > 解决方案 > 当元素值只有空间时,XmlReader XSD 验证失败

问题描述

使用 .Net XMLReader 读取 xml 时,由于元素仅包含空格,XSD 验证在以下 xml 上失​​败:

 <Text> </Text>

这是 XSD 的相关部分:

<xs:simpleType name="MaxText">
    <xs:restriction base="xs:string">
        <xs:minLength value="1"/>
        <xs:maxLength value="25"/>
    </xs:restriction>
</xs:simpleType>

<xs:element name="Text" type="MaxText">
</xs:element>

这是生成的错误消息:

 The 'Text' element is invalid - The value '' is invalid according to its datatype 'MaxText' - The actual length is less than the MinLength value.

执行这行代码时会引发验证错误:

 var element = XNode.ReadFrom(XmlReader) as XElement;

这不应该验证失败,但我不确定我需要改变什么来解决这个问题。

这是重现该问题的控制台应用程序的代码:

using System;
using System.Text;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Linq;
using System.IO;

namespace XmlReader
{
class Program
{
    static void Main(string[] args)
    {
        var xmlReaderSettings = SetXmlReaderSettings();

        using(var memoryStream = GetXml())
        {
            using(var xmlReader = System.Xml.XmlReader.Create(memoryStream, xmlReaderSettings))
            {
                while (xmlReader.Read())
                {
                    if (xmlReader.NodeType == XmlNodeType.Element)
                    {
                        if (xmlReader.LocalName.Equals("Text"))
                        {
                            var element = XNode.ReadFrom(xmlReader) as XElement;
                            Console.WriteLine(element);
                        }
                    }
                }
            }
        }
        Console.WriteLine("All elements parsed. Press any key to continue...");
        Console.ReadLine();
    }

    private static XmlReaderSettings SetXmlReaderSettings()
    {
        var xmlReaderSettings = new XmlReaderSettings
        {
            ConformanceLevel = ConformanceLevel.Document,
            DtdProcessing = DtdProcessing.Ignore,
            CloseInput = true,
            IgnoreWhitespace = true,
            IgnoreComments = true,
            IgnoreProcessingInstructions = true,
            ValidationType = ValidationType.Schema,
            Schemas = GetXmlSchemaSet()
        };

        xmlReaderSettings.ValidationEventHandler += OnValidationEventHandler;
        return xmlReaderSettings;
    }

    private static XmlSchemaSet GetXmlSchemaSet()
    {
        var schemaCollection = new XmlSchemaSet();
        var xsd = @"
                            <xs:schema id=""XMLSchema1"" 
                                targetNamespace=""http://tempuri.org/XMLSchema1.xsd"" 
                                elementFormDefault=""qualified"" 
                                xmlns=""http://tempuri.org/XMLSchema1.xsd"" 
                                xmlns:mstns=""http://tempuri.org/XMLSchema1.xsd"" 
                                xmlns:xs=""http://www.w3.org/2001/XMLSchema"">
                            <xs:element name=""Items"" />
                            <xs:simpleType name=""MaxText"">
                            <xs:restriction base=""xs:string""> 
                            <xs:minLength value=""1"" />  
                            <xs:maxLength value=""25"" />   
                            </xs:restriction>
                            </xs:simpleType>
                            <xs:element name=""Text"" type=""MaxText"">
                            </xs:element>
                            </xs:schema>
                    ";
        var reader = new XmlTextReader(new StringReader(xsd));
        schemaCollection.Add(XmlSchema.Read(reader, null));
        schemaCollection.Compile();
        return schemaCollection;
    }

    private static MemoryStream GetXml()
    {
        var xmlString = @"<?xml version=""1.0"" encoding=""utf-8""?>
                            <Items xmlns=""http://tempuri.org/XMLSchema1.xsd"">
                            <Text>   </Text> 
                            </Items>";
        var byteArray = Encoding.ASCII.GetBytes(xmlString);
        return new MemoryStream(byteArray);            
    }

    private static void OnValidationEventHandler(object sender, ValidationEventArgs e)
    {
        Console.WriteLine($"ValidationError: {e.Message}");
    }
}
}

标签: c#.netxmlreader

解决方案


如果您不想拥有这个空间,请尝试将 MaxLength 设置为 0

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:simpleType name="MaxText">
        <xs:restriction base="xs:string">
            <xs:minLength value="0"/>
            <xs:maxLength value="25"/>
        </xs:restriction>
   </xs:simpleType>

   <xs:element name="Text" type="MaxText"/>
</xs:schema>

推荐阅读