【问题标题】:XML validating with XSD failing due to 'refname' not declared despite refname not allowed for schemasXML 验证与 XSD 失败,由于 'refname' 未声明,尽管 refname 不允许用于模式
【发布时间】:2012-10-26 03:50:53
【问题描述】:

我正在尝试通过 C# 代码中的 XSD 验证 XML。但是它不断抛出 XmlSchemaValidationException,即“'refname' 属性未声明。”。

进行验证的代码:

XmlReaderSettings xmlSettings = new XmlReaderSettings();
            xmlSettings.Schemas = new System.Xml.Schema.XmlSchemaSet();
            xmlSettings.Schemas.Add(null, @"\\[Network-drive path]\KVSchemaMod.xsd");
            xmlSettings.ValidationType = ValidationType.Schema;
            xmlSettings.DtdProcessing = DtdProcessing.Parse;
            xmlSettings.ValidationFlags = XmlSchemaValidationFlags.AllowXmlAttributes;
            xmlSettings.ValidationFlags = XmlSchemaValidationFlags.ProcessInlineSchema;
            xmlSettings.ValidationFlags = XmlSchemaValidationFlags.ReportValidationWarnings;
            XmlReader reader = XmlReader.Create(@"\\[Network-drive path]\KV_Article.xml", xmlSettings);

            // Parse the file.
            while (reader.Read()) ;

XSD(去除重复部分):

<?xml version="1.0" encoding="iso-8859-1"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:sql="urn:schemas-microsoft-com:mapping-schema">
<xs:annotation>
    <xs:appinfo>
        <sql:relationship name="ProductIdentifier"
        parent="tblKVProduct"
        parent-key="record_reference"
        child="tblKVProductIdentifier"
        child-key="record_reference" />
... (More SQL-mappings)
<xs:element name="ONIXMessage" sql:is-constant="1">
    <xs:complexType>
        <xs:sequence>
            <xs:element minOccurs="0" maxOccurs="unbounded" name="Product" sql:relation="tblKVProduct">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element minOccurs="1" maxOccurs="1" name="RecordReference" sql:field="record_reference" >
                            <xs:simpleType>
                                <xs:restriction base="xs:string">
                                    <xs:minLength value="0"/>
                                    <xs:maxLength value="32"/>
                                </xs:restriction>
                            </xs:simpleType>
                        </xs:element>
...(More elements under Product)

要验证的 XML(ONIX 标准):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ONIXMessage SYSTEM "http://www.editeur.org/onix/2.1/reference/onix-  international.dtd">
<ONIXMessage>
<Product>
    <RecordReference>0786606274</RecordReference>
    <NotificationType>03</NotificationType>
    <ProductIdentifier>
        <ProductIDType>01</ProductIDType>
        <IDTypeName>Kustantajan tuotenumero</IDTypeName>
        <IDValue>95535</IDValue></ProductIdentifier>
    <ProductIdentifier>
        <ProductIDType>02</ProductIDType>
        <IDValue>0786606274</IDValue></ProductIdentifier>
    <ProductIdentifier>
        <ProductIDType>03</ProductIDType>
        <IDValue>9780786606276</IDValue>
    </ProductIdentifier>
...(And more Product-fields)

XML 也有一个 Header 标记作为 ONIXMessage 的第一个子标记(紧随其后的所有 Product 标记也是 ONIXMessage 的子标记),但由于架构中没有引用任何字段,我看不出它们如何导致此特定错误。

当我用谷歌搜索时,我在 XmlSchemaElement.RefName 属性 (MSDN Definition) 上读到了错误,它甚至明确表示“如果包含元素是架构元素,则无法设置值。” 既然 XSD 就是这种情况,我不明白为什么它会抛出关于它没有被声明的错误。

我一直试图找出这是否与缺少命名空间有关,但在我看来这应该不是问题,因为 XML 和 XSD 中都没有。或者是否需要在根元素上强制命名空间以验证 XML?

验证代码确实可以与另一组 XML/XSD 一起使用(尽管它们的构建方式非常不同),但这可能只是侥幸,而错误实际上是我验证的方式吗?

为了补全,XML 中的 Header 标记:

<Header>
    <FromCompany></FromCompany>
    <FromPerson></FromPerson>
    <FromEmail></FromEmail>
    <AddresseeIdentifier>
        <AddresseeIDType></AddresseeIDType>
        <IDTypeName></IDTypeName>
        <IDValue></IDValue>
    </AddresseeIdentifier>
    <ToCompany></ToCompany>
    <ToPerson></ToPerson>
    <MessageNumber></MessageNumber>
    <SentDate></SentDate>
    <MessageNote></MessageNote>
</Header>

【问题讨论】:

    标签: c# xsd xml-validation


    【解决方案1】:

    由于您没有提供完整的示例,因此无法重现您的问题。如果您想要基于推测以外的任何答案,您需要将您的架构和数据缩减为说明问题的最小示例,以便问题回答者可以重现问题并更详细地研究它。当然,经常会发生这样的情况,即你的问题在这个过程中消失了,因为你在寻找问题的一个小例子的过程中发现出了什么问题。但这只是您必须承担的风险。

    不过,我会继续推测。 XMLSchemaElement 对象上的 RefName 属性几乎可以肯定是一个红鲱鱼。该消息听起来更像是您尝试验证的 XML 在某处(在您省略的位中)有一个名为 refname 的属性,并且您的 XSD 架构没有定义它。当然,您提供的 XSD 片段没有定义。

    http://www.editeur.org/onix/2.1/reference/onix-international.dtd(您在 XML 中指向)定义的词汇表确实将refname 定义为许多元素的属性(可能是所有元素,尽管我没有单独检查每个元素)。因此,ONIXMessage 元素可能包含具有refname 属性的后代,这一点也不令人难以置信。

    实际上,这不仅仅是不可信;这是肯定的。

    您的 XML 指向的 DTD 为所有元素(至少是我见过的所有元素)的 refname 属性提供了一个默认值,您的 XSD 模式声明似乎没有准备好。也就是说,模式验证器看到的文档的第一个开始标签不是&lt;ONIXMessage&gt;,而是&lt;ONIXMessage refname="ONIXMessage" shortname="ONIXmessage"&gt;

    如果您不使用 www.editeur.org 提供的 XSD,最简单的方法可能是重新考虑该决定并使用 editeur.org 中的架构,而不是自己滚动。它包括 refname 和 shortname 属性的声明。如果您正在使用该架构,或者更确切地说是尝试使用它,则出现严重错误,您的验证器没有找到或读取它。在这种情况下,最好的方法是找出系统找不到正确架构文档的原因。

    【讨论】:

    • 出于某种原因,我从未考虑过使用 2 种不同的模式,一种用于验证(来自 Editeur),另一种用于批量加载(内部版本)。非常感谢您的推测,即使我未能构建一个可以接受的问题! =) 像魅力一样工作。
    猜你喜欢
    • 2012-08-26
    • 2014-11-20
    • 1970-01-01
    • 1970-01-01
    • 2022-06-17
    • 1970-01-01
    • 1970-01-01
    • 2019-06-23
    • 1970-01-01
    相关资源
    最近更新 更多