【问题标题】:Problem when using extension in a XML Schema在 XML Schema 中使用扩展时出现问题
【发布时间】:2020-02-20 22:29:34
【问题描述】:

我需要创建一个扩展简单类型的 XML 模式,因此我可以添加一个属性以供以后在我的代码中使用(此属性不会在生成的 XML 中使用)。它必须是一个扩展,因为我必须对这些类型设置一些限制。

问题:msg_1 和 msg_2 必须有一些同名的元素,这会导致错误。

错误:cos-element-consistent:类型“#AnonType_msg”的错误。模型组中出现多个名称为“代码”且类型不同的元素。

我知道让这些元素名称不同可以解决问题,但不幸的是它们必须相同。

代码如下:

<xsd:element name="msg">
    <xsd:complexType>
        <xsd:sequence>
            <xsd:group ref="header"/>    
            <xsd:choice>
                <xsd:group ref="msg_1"/>
                <xsd:group ref="msg_2"/>
            </xsd:choice>
        </xsd:sequence>
        <xsd:attribute name="IdMsg" type="IdM" use="required"/>
    </xsd:complexType>
</xsd:element>

<xsd:group id="M39" name="msg_1">
    <xsd:sequence>
        <xsd:element name="Code">
            <xsd:complexType>
                <xsd:simpleContent>
                    <xsd:extension base="Code">
                        <xsd:attribute name="compact" use="prohibited"/>
                    </xsd:extension>
                </xsd:simpleContent>
            </xsd:complexType>
        </xsd:element>
        <xsd:element name="ID">
            <xsd:complexType>
                <xsd:simpleContent>
                    <xsd:extension base="ID">
                        <xsd:attribute name="compact" use="prohibited"/>
                    </xsd:extension>
                </xsd:simpleContent>
            </xsd:complexType>
        </xsd:element>
   </xsd:sequence>
</xsd:group>
<xsd:group id="M40" name="msg_2">
    <xsd:sequence>
        <xsd:element name="Code">
            <xsd:complexType>
                <xsd:simpleContent>
                    <xsd:extension base="Code">
                        <xsd:attribute name="compact" use="prohibited"/>
                    </xsd:extension>
                </xsd:simpleContent>
            </xsd:complexType>
        </xsd:element>
        <xsd:element name="ID">
            <xsd:complexType>
                <xsd:simpleContent>
                    <xsd:extension base="ID">
                        <xsd:attribute name="compact" use="prohibited"/>
                    </xsd:extension>
                </xsd:simpleContent>
            </xsd:complexType>
        </xsd:element>
    </xsd:sequence>
</xsd:group>

<xsd:simpleType name="IdM">
    <xsd:restriction base="xsd:unsignedByte">
        <xsd:minInclusive value="29"/>
        <xsd:maxInclusive value="42"/>
    </xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ID">
    <xsd:restriction base="xsd:unsignedByte">
        <xsd:minInclusive value="0"/>
        <xsd:maxInclusive value="255"/>
    </xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="Code">
    <xsd:restriction base="xsd:unsignedByte">
        <xsd:minInclusive value="0"/>
        <xsd:maxInclusive value="13"/>
    </xsd:restriction>
</xsd:simpleType>
<xsd:group id="M2" name="header">
    <xsd:sequence>
        <xsd:element fixed="2" name="Version" type="xsd:unsignedInt"/>
        <xsd:element name="Timer" type="xsd:unsignedLong"/>
    </xsd:sequence>
</xsd:group>

有什么解决办法吗?

更新: 断言并非如此。基本上,我有两个不同的消息(组)共享一些参数(子元素)。

我想命名空间可以解决问题,但我试图避免它,因为最好只有 1 个 .xsd 文件。

我得到了关于歧义等的部分,但它没有回答为什么后面的代码验证得很好。代码如下:

<xsd:element name="msg">
    <xsd:complexType>
        <xsd:sequence>
            <xsd:group ref="header"/>    
            <xsd:choice>
                <xsd:group ref="msg_1"/>
                <xsd:group ref="msg_2"/>
            </xsd:choice>
        </xsd:sequence>
        <xsd:attribute name="IdMsg" type="IdM" use="required"/>
    </xsd:complexType>
</xsd:element>

<xsd:group id="M39" name="msg_1">
    <xsd:sequence>
        <xsd:element name="anything" type="code"/>
        <xsd:element name="something_else" type="code"/>
   </xsd:sequence>
</xsd:group>
<xsd:group id="M40" name="msg_2">
    <xsd:sequence>
        <xsd:element name="nothing" type="code"/>
        <xsd:element name="something_else" type="code"/>
    </xsd:sequence>
</xsd:group>

<xsd:simpleType name="code">
    <xsd:restriction base="xsd:unsignedByte">
        <xsd:minInclusive value="0"/>
    </xsd:restriction>
</xsd:simpleType>

<xsd:simpleType name="IdM">
    <xsd:restriction base="xsd:unsignedByte">
        <xsd:minInclusive value="29"/>
        <xsd:maxInclusive value="42"/>
    </xsd:restriction>
</xsd:simpleType>


<xsd:group id="M2" name="header">
    <xsd:sequence>
        <xsd:element fixed="2" name="Version" type="xsd:unsignedInt"/>
        <xsd:element name="Timer" type="xsd:unsignedLong"/>
    </xsd:sequence>
</xsd:group>

奇怪的是,它甚至可以使用 2 个共享相同名称的元素 (something_else)。如果从 msg_1 和 msg_2 中取出名为“anything”和“nothing”的元素,则会返回关于歧义的问题。有什么解释吗?我看不出这种行为的原因,所以我一定是遗漏了一些东西。

PS:这里的代码只是一个例子,我知道这2组是完全一样的。我编写了代码来说明问题。在我的应用程序中,这些组是不同的,即使它们共享一些元素。

【问题讨论】:

    标签: xml schema


    【解决方案1】:

    XSD 的设计目的是,当验证器遇到特定元素时,验证器仅根据其名称(和包含元素的类型)就可以清楚地知道在哪里可以找到该元素的规则。您的架构显然违反了该规则:当遇到 Code 时,有两种可能的定义,它不知道该选择哪一种。

    如果您尝试为规则是上下文相关的现有 XML 文档类编写 XSD,那么您可能能够以不同的方式表达约束,例如使用 XSD 1.1 断言,或使用Schematron。

    【讨论】:

    • 你好。感谢你的回答。我刚刚用更多信息更新了这个问题。不幸的是,这里的断言并非如此。
    猜你喜欢
    • 2020-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-27
    • 2010-10-12
    • 1970-01-01
    • 2016-02-13
    • 1970-01-01
    相关资源
    最近更新 更多