【问题标题】:element is nil and must be empty元素为 nil 且必须为空
【发布时间】:2021-08-01 07:12:02
【问题描述】:

我有一个使用 XML 进行通信的旧版 c++ 应用程序,其中一个元素具有以下 xml 架构。

        <xs:simpleType name="CountryType">
                <xs:restriction base="xs:string">
                        <xs:minLength value="2"/>
                        <xs:maxLength value="3"/>
                        <xs:whiteSpace value="collapse"/>
                        <xs:enumeration value="ABW"/>
                        <xs:enumeration value="ALB"/>
                        <xs:enumeration value="ALG"/>
                        <xs:enumeration value="AND"/>
                        ...
                </xs:restriction>
        </xs:simpleType>

        <xs:element name="Country" nillable="true">
                <xs:complexType>
                        <xs:simpleContent>
                                <xs:extension base="CountryType">
                                        <xs:attribute ref="searchCriteria" use="optional"/>
                                </xs:extension>
                        </xs:simpleContent>
                </xs:complexType>
        </xs:element>

即使 nillable 设置为 true,但是当

<Country xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>

传入,xerces-c schema 验证失败,报错“element 'Country' is nil and must be empty”。

为什么会失败? CountryType 的 minLength 为 2,所以我认为应该限制它为空,但是当输入为空并且接受以下内容时,架构验证不会抱怨。

<Country></Country>

有没有办法让它接受 nil?

<Country xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>

使用的 xerces-c 库是 3.0 版。架构解析器设置为:

      XercesDOMParser *schemaParser = null;
      schemaParser = new XercesDOMParser();
      schemaParser->setDoNamespaces(true);
      schemaParser->setDoSchema(true);
      schemaParser->setValidationScheme(XercesDOMParser::Val_Always);
      schemaParser->setExternalNoNamespaceSchemaLocation(getSchemaFile());
      schemaParser->setIncludeIgnorableWhitespace(false);
      schemaParser->cacheGrammarFromParse(true);

【问题讨论】:

    标签: xml xsd schema


    【解决方案1】:

    根据该架构,XML 文档是有效的。我已经使用在线 XSD 验证器进行了检查。所以乍一看,这看起来像是一个 xerces-c 缺陷。然而,有两件事让我对这个结论持谨慎态度:

    1. xsi:nil 与空标签一起使用是标准用法。如果在像 xerces-c 这样古老的 XML 处理器中这样的缺陷一直存在,我会感到非常惊讶。
    2. 你说&lt;Country&gt;&lt;/Country&gt;被接受了。根据 XML 规范,&lt;Country/&gt;&lt;Country&gt;&lt;/Country&gt; 之间没有区别。 (见https://www.w3.org/TR/xml/#sec-starttags,规则[43])。同样,xerces-c 在这方面可能存在缺陷,但这会有点令人惊讶(无论如何,对我来说)。

    您可能使用的是非常旧的 xerces-c 版本,存在一些未修复的缺陷 - 可能值得更新到最新版本。如果这不能解决问题,那么我会联系 xerces-c 的维护人员:https://xerces.apache.org/xerces-c/feedback.html

    【讨论】:

    • xerces-c lib 使用的是 3.0,我添加了使用的模式解析器设置。 &lt;Country/&gt; 有效,&lt;Currency xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/&gt; 也有效,但 &lt;Currency xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/&gt; 失败。它不喜欢 xsi:nl="true" 属性。由于元素被标记为 nillable,使用 XML 生成工具(如 JAXB)的用户包含该属性,但它会失败。
    • 简单类型,例如带有xsi:nil="true"的字符串,所以我想知道complexType元素是否有一些特殊情况。
    • 听起来确实像 xerces-c 缺陷。如果存在 xsi:nil="true" 则标签必须包含空内容。我认为 xerces-c 对标签是否为空感到困惑。我建议你联系他们的邮件列表,提供你的 xsd 和 XML。
    • 会的。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2021-02-19
    • 1970-01-01
    • 1970-01-01
    • 2016-09-14
    • 1970-01-01
    • 1970-01-01
    • 2019-03-11
    • 1970-01-01
    相关资源
    最近更新 更多