【问题标题】:XSD validation not failing trailing newlineXSD 验证没有失败尾随换行符
【发布时间】:2016-11-17 15:20:37
【问题描述】:

Xml 验证不是我接触的东西,除非我必须这样做,所以我可能遗漏了一些愚蠢的东西,到目前为止,我在谷歌上搜索任何帮助都没有成功。我的问题是我的类型有一个限制,它只能是字母或空格。带有前导换行符的元素验证失败,但尾随换行符通过。如何让尾随换行符失败?

我创建了一个精简的测试用例,如下所示:

验证码:

public List<XsdValidationError> ValidateXmlAgainstXsd(String xml, String xsdFilePath, Boolean processSchemaLocation = false)
{
    var ret = new List<XsdValidationError>();
    var xss = new XmlSchemaSet();

    var xmlUrlResolver = new XmlUrlResolver();
    xmlUrlResolver.CachePolicy = new RequestCachePolicy(RequestCacheLevel.Default);
    xss.XmlResolver = xmlUrlResolver;

    var xsdXElement = XElement.Parse(File.ReadAllText(xsdFilePath));

    var targetNamespaceAttribute = xsdXElement.Attribute("targetNamespace");
    xss.Add(targetNamespaceAttribute != null ? targetNamespaceAttribute.Value : "", xsdFilePath);


    var settings = new XmlReaderSettings();
    settings.ValidationType = ValidationType.Schema;
    settings.Schemas = xss;
    settings.ValidationFlags = XmlSchemaValidationFlags.ProcessInlineSchema;

    if (processSchemaLocation)
        settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
    settings.ValidationEventHandler += (sender, e) =>
        {
            var xve = new XsdValidationError { Message = e.Message, LineNumber = e.Exception.LineNumber, LinePosition = e.Exception.LinePosition };

            ret.Add(xve);
        };

    using (var sr = new StringReader(xml))
    {
        var xr = XmlReader.Create(sr, settings);

        while (xr.Read());

        return ret;
    }
}

public class XsdValidationError
{
    public String Message { get; set; }
    public int LineNumber { get; set; }
    public int LinePosition { get; set; }

    public override string ToString()
    {
        return String.Format("Line {0:n0}, Position {1:n0}: {2}", this.LineNumber, this.LinePosition, this.Message);
    }
}

输入 XML 和 XSD:

<People>
    <Person>Hello Person One
</Person>
    <Person>Hello Person Two</Person>
    <Person>
Hello Person Three</Person>
</People>

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="People">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="Person" maxOccurs="unbounded">
                    <xs:simpleType>
                        <xs:restriction base="xs:string">
                            <xs:pattern value="[a-zA-Z ]+"/>
                        </xs:restriction>
                    </xs:simpleType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

在 XML 中,第一个人没有失败,第二个人按理说通过了,第三个人按预期通过了。我需要一个人也失败。

我无法更改输入 XML 或 XSD。 Visual Studio 正确验证文件。有什么想法吗?

【问题讨论】:

    标签: c# xml xsd


    【解决方案1】:

    我认为这是 Microsoft XSD 解析器的一个怪癖/错误。 xs:string 类型的定义是:-

     <xsd:simpleType name="string" id="string">
       <xsd:restriction base="xsd:anySimpleType">
       <xsd:whiteSpace value="preserve"/>
       </xsd:restriction>
     </xsd:simpleType>
    

    由于空白方面设置为“保留”,它应该包含元素中的所有内容、空白和所有内容。

    但是,您已经注意到它忽略了尾随空格。除了在代码中手动应用验证规则之外,您似乎无能为力。

    顺便说一句,它在 Xerces 中按预期进行验证(前导和尾随空格都出错)。

    【讨论】:

    • 我怀疑这是一个像这样的错误,只是因为我无法通过谷歌搜索找到与此问题类似的任何其他内容。我不认为我会是第一个遇到这个问题的人。但是,Xerces 给了我一些其他的尝试,所以谢谢你!
    【解决方案2】:

    我发现,如果我切换到使用 XmlDocument 加载 xml,它会正确验证,但我会丢失行号信息。我不确定幕后发生了什么,但更改为这个将在我的情况下正确验证。

    var xd = new XmlDocument();
    xd.LoadXml(xml);
    var xr = XmlReader.Create(new XmlNodeReader(xd), settings);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-05-11
      • 2019-06-23
      • 1970-01-01
      • 2019-05-18
      • 1970-01-01
      • 2021-11-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多