【问题标题】:XSD Schema Validation seems to ignore required AttributesXSD Schema Validation 似乎忽略了必需的属性
【发布时间】:2017-12-04 18:59:09
【问题描述】:

我正在使用 XmlReader 来对照我的 XSD 架构文件验证我的 XMLfiles,它正在处理一个例外:它没有报告缺少必需的属性。

但是,它会报告不符合 XSD 的属性(名称拼写错误,不允许的内容)

例如,这两个都将在没有警告的情况下验证,即使 both 属性都是必需的:

<Margin Units="IN">
<Margin Units="IN" Center="true">

然而,这些会引发警告(其中 Units 是枚举,Center 是布尔值):

<Margin Units="IN" Center="123">
<Margin Units="abc" Center="123">

为了让事情变得更加混乱(对我来说)相同的文件和条件将无法使用 Notepad++ 插件“XML 工具”进行验证,并且将无法使用 XMLSpy。

似乎只有 C# / .Net 不会发出警告。

这是我的验证码:

public string ValidateXML(string sXmlString)
{
    validationErr = "";
    try
    {
        XmlReaderSettings settings = new XmlReaderSettings();
        settings.CloseInput = true;
        settings.ValidationEventHandler += ValidationHandler;
        settings.ValidationType = ValidationType.Schema;
        settings.ValidationFlags = XmlSchemaValidationFlags.ReportValidationWarnings |
                                   XmlSchemaValidationFlags.ProcessIdentityConstraints |
                                   XmlSchemaValidationFlags.ProcessSchemaLocation;

        StringReader r = new StringReader(sXmlString);
        XmlReader validatingReader = XmlReader.Create(r, settings);
        XmlDoc = new XmlDocument();
        XmlDoc.Load(validatingReader); //errors are put into the validationErr var in the ValidationHandler
    }
    catch (Exception exc)
    {
        validationErr = "XML EXCEPTION: " + exc.Message + Environment.NewLine + validationErr;
    }
    return validationErr;
}

private static void ValidationHandler(object sender, ValidationEventArgs e)
{
    if (e.Severity == XmlSeverityType.Error || e.Severity == XmlSeverityType.Warning)
    {
        validationErr += "XML Parse Error Line: " +
                    e.Exception.LineNumber + " Position: " +
                    e.Exception.LinePosition + " Message: " +
                    e.Exception.Message + Environment.NewLine;
    }
}

这是我的 XSD:

    <?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
    <xs:element name="SampleSchema">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="Margins" minOccurs="0"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="Margins">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="Header" minOccurs="0"/>
                <xs:element ref="Footer" minOccurs="0"/>
                <xs:element ref="LeftSide" minOccurs="0"/>
                <xs:element ref="RightSide" minOccurs="0"/>
            </xs:sequence>
            <xs:attribute ref="Units" use="required"/>
            <xs:attribute ref="CenterHorizontal" use="required"/>
            <xs:attribute ref="CenterVertical" use="required"/>
            <xs:attribute ref="PriorityHorizontal" use="required"/>
            <xs:attribute ref="PriorityVertical" use="required"/>
        </xs:complexType>
    </xs:element>
    <xs:element name="Header">
        <xs:simpleType>
            <xs:restriction base="xs:decimal">
                <xs:minInclusive value="0"/>
            </xs:restriction>
        </xs:simpleType>
    </xs:element>
    <xs:element name="Footer">
        <xs:simpleType>
            <xs:restriction base="xs:decimal">
                <xs:minInclusive value="0"/>
            </xs:restriction>
        </xs:simpleType>
    </xs:element>
    <xs:element name="LeftSide">
        <xs:simpleType>
            <xs:restriction base="xs:decimal">
                <xs:minInclusive value="0"/>
            </xs:restriction>
        </xs:simpleType>
    </xs:element>
    <xs:element name="RightSide">
        <xs:simpleType>
            <xs:restriction base="xs:decimal">
                <xs:minInclusive value="0"/>
            </xs:restriction>
        </xs:simpleType>
    </xs:element>
    <xs:attribute name="Units" default="PT">
        <xs:simpleType>
            <xs:restriction base="xs:string">
                <xs:enumeration value="IN"/>
                <xs:enumeration value="MM"/>
                <xs:enumeration value="PT"/>
            </xs:restriction>
        </xs:simpleType>
    </xs:attribute>
    <xs:attribute name="CenterHorizontal" type="xs:boolean" default="true">
    </xs:attribute>
    <xs:attribute name="CenterVertical" type="xs:boolean" default="true">
    </xs:attribute>
    <xs:attribute name="PriorityHorizontal" default="Left">
        <xs:simpleType>
            <xs:restriction base="xs:string">
                <xs:enumeration value="Left"/>
                <xs:enumeration value="Right"/>
            </xs:restriction>
        </xs:simpleType>
    </xs:attribute>
    <xs:attribute name="PriorityVertical" default="Header">
        <xs:simpleType>
            <xs:restriction base="xs:string">
                <xs:enumeration value="Header"/>
                <xs:enumeration value="Footer"/>
            </xs:restriction>
        </xs:simpleType>
    </xs:attribute>
</xs:schema>

这是我的 XML:

<?xml version="1.0" encoding="UTF-8"?>
<SampleSchema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="sample.xsd">
    <Margins Units="PT" CenterHorizontal="false" CenterVertical="false" PriorityVertical="Header">
        <Header>36</Header>
        <Footer>36</Footer>
        <LeftSide>36</LeftSide>
        <RightSide>36</RightSide>
    </Margins>
</SampleSchema>

一旦初始验证成功,我是否必须编写代码来显式检查 XML 文件中的属性?

或者有没有办法让 XmlReader Validation 抛出这些警告?

【问题讨论】:

  • 您能否附上您的 xsd 和示例 xml,它们应该会失败但不会失败?
  • @Evk - 好的,我已经添加了我的 xsd 和 xml 示例
  • 您真的需要为所需属性设置默认值吗?您是否尝试过删除默认设置?
  • @ViacheslavIvanov - 如果默认值是我的问题的原因,我可以删除它们
  • @ViacheslavIvanov - 明白了!删除属性的默认值解决了这个问题。现在报告缺少的属性。感谢您指出了这一点。如果你让你评论一个答案,我很乐意选择它。

标签: c# xml


【解决方案1】:

尝试删除属性定义中的“默认”。 MSDN says:

…如果属性实际上不在实例文档中,则模式的处理器应该像使用默认值指定属性一样行事。

看起来这就是“必需”验证不起作用的原因。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-28
    • 2012-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多