验证XML时出错

时间:2017-07-05 15:45:22

标签: c# .net xsd-validation

System.ArgumentNullException:值不能是未定义的

堆栈跟踪:

   at System.Xml.Linq.XAttribute..ctor(XName name, Object value)
   at System.Xml.Schema.XNodeValidator.ValidateAttributes(XElement e)
   at System.Xml.Schema.XNodeValidator.ValidateElement(XElement e)
   at System.Xml.Schema.XNodeValidator.ValidateNodes(XElement e)
   at System.Xml.Schema.XNodeValidator.ValidateElement(XElement e)
   at System.Xml.Schema.XNodeValidator.Validate(XObject source, XmlSchemaObject partialValidationType, Boolean addSchemaInfo)
   at System.Xml.Schema.Extensions.Validate(XDocument source, XmlSchemaSet schemas, ValidationEventHandler validationEventHandler, Boolean addSchemaInfo)

源代码:

    var xmlPath = @"C:\XSDTEST\test.xml";

    XDocument doc = XDocument.Load(xmlPath);
    XmlSchemaSet xss = new XmlSchemaSet();

    xss.Add("",@"C:\XSDTEST\test.xsd");

    XmlReaderSettings xrs = new XmlReaderSettings();
    xrs.ValidationType = ValidationType.Schema;
    xrs.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
    xrs.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
    xrs.ValidationFlags |= XmlSchemaValidationFlags.ProcessIdentityConstraints;
    xrs.Schemas = xss;

    doc.Validate(xss, new ValidationEventHandler((s, args) => { }), true);

test.xsd:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <xsd:element name="Root">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element name="Child1" minOccurs="1" maxOccurs="1"/>
                <xsd:element ref="Child2" minOccurs="1" maxOccurs="1"/>
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>
    <xsd:element name="Child2" type="Child2ElemType"/>
    <xsd:complexType name="Child2ElemType">
        <xsd:attribute ref="align" default="left"/>
    </xsd:complexType>
    <xsd:attribute name="align" type="alignAttType"/>
    <xsd:simpleType name="alignAttType">
        <xsd:restriction base="xsd:NMTOKEN">
            <xsd:enumeration value="left"/>
            <xsd:enumeration value="right"/>
            <xsd:enumeration value="center"/>
            <xsd:enumeration value="justify"/>
            <xsd:enumeration value="char"/>
        </xsd:restriction>
    </xsd:simpleType>
</xsd:schema>

的test.xml:

<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="file:///C:/XSDTEST/test.xsd">
    <Child1/>
    <Child2/>
</Root>

问题:默认=“左”:

<xsd:attribute ref="align" default="left"/>

我认为验证过程尝试使用默认值创建“align”属性,但XAttribute构造函数为null,而不是“left”。

如果我将默认值设置为<xsd:attribute name="align" type="alignAttType" default="left"/>,则可以正常工作。

如果我将默认值设置为<xsd:attribute ref="align" default="left"/>,我将收到错误。

我可以在验证过程中禁用使用默认值创建属性吗?

正确处理默认值的设置是什么?

2 个答案:

答案 0 :(得分:1)

根据XSD,“ref =”必须是“合格名称”

https://msdn.microsoft.com/en-us/library/ms256143(v=vs.110).aspx

  

ref值必须是限定名称(QName)

由于您的XSD没有命名空间,因此验证器看起来无法找到引用的属性。

另外,看看这个相关的SO问题: How to reference an attribute in xsd

  

在XML Schemas中,所有全局元素,属性或类型定义都必须是限定的

以下是相关的标准提取物: https://www.w3.org/TR/REC-xml-names/#defaulting

  

默认名称空间声明不直接应用于属性名称

     

未加前缀的属性名称的命名空间名称始终没有值

以下链接专门讨论了不合格的全局属性 Unqualified XSD global attribute references

答案 1 :(得分:0)

加载模式后,我建立了临时解决方法:

       foreach (XmlSchema schema in xss.Schemas())
            {
                foreach (System.Collections.DictionaryEntry ag in schema.AttributeGroups)
                {
                    if (ag.Value is XmlSchemaAttributeGroup)
                    {
                        var attributeGroup = (XmlSchemaAttributeGroup)ag.Value;


                        foreach (var attributeOrGroup in attributeGroup.Attributes)
                        {
                            if (attributeOrGroup is XmlSchemaAttribute)
                            {
                                var attribute = (XmlSchemaAttribute)attributeOrGroup;
                                if (attribute.DefaultValue != null)
                                {
                                    attribute.DefaultValue = null;
                                }
                                if (attribute.FixedValue != null)
                                {
                                    attribute.FixedValue = null;
                                }
                            }
                        }
                    }
                }
                foreach (System.Collections.DictionaryEntry st in schema.SchemaTypes)
                {
                    if (st.Value is XmlSchemaComplexType)
                    {
                        var c = (XmlSchemaComplexType)st.Value;

                        foreach (var g in c.Attributes)
                        {
                            if (g is XmlSchemaAttribute)
                            {
                                var attr = (XmlSchemaAttribute)g;
                                if (attr.DefaultValue != null)
                                {
                                    attr.DefaultValue = null;

                                }
                                if (attr.FixedValue != null)
                                {
                                    attr.FixedValue = null;
                                }

                            }
                        }
                    }
                }
            }