0

我正在尝试通过 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 定义),它甚至明确表示“如果包含元素是架构元素,则无法设置该值。 ”因为 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>
4

1 回答 1

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 模式声明似乎没有准备好。也就是说,模式验证器看到的文档的第一个开始标签不是<ONIXMessage>but <ONIXMessage refname="ONIXMessage" shortname="ONIXmessage">

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

于 2012-10-25T19:50:53.267 回答