【问题标题】:XmlReader XSD validation failing when element value only has space当元素值只有空间时,XmlReader XSD 验证失败
【发布时间】:2019-07-14 10:12:44
【问题描述】:

使用 .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# .net xmlreader


    【解决方案1】:

    如果您不希望有这个空间,请尝试将 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>
    

    【讨论】:

    • 无效,但 有效,因此不能设置 minLength=0。当我使用 XMLSpy 验证 XML 时,它是有效的 XML,所以我不明白为什么在使用 .Net XmlReader 时它会失败。
    • .Net XmlReader 上可能存在的错误?
    【解决方案2】:

    设置 IgnoreWhitespace = false 解决了这个问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-16
      • 1970-01-01
      • 1970-01-01
      • 2019-06-23
      • 1970-01-01
      • 2020-03-17
      • 2019-05-18
      • 1970-01-01
      相关资源
      最近更新 更多