XSD - 当使用抽象机制和其他命名空间中的替换组时,我遇到了一种奇怪的行为

时间:2012-02-29 07:24:25

标签: xml xsd

我有以下spml-example.xsd,它定义了一个包含action元素的命令元素:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    targetNamespace="http://www.myexample.com/command" xmlns:tns="http://www.myexample.com/command"
    elementFormDefault="qualified">

    <xs:element name="Action" type="tns:ActionType" abstract="true" />

    <xs:complexType name="ActionType" abstract="true">
        <xs:attribute name="result" type="xs:string" />
    </xs:complexType>

    <xs:element name="Command">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="tns:Action" minOccurs="1" maxOccurs="unbounded" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>

</xs:schema>

正如您所看到的,该操作是抽象的,因此具体实现可以替代它。 所以我有两种类型的动作来扩展这个动作:
第一个是spml-test-actions.xsd,它定义了一个读取动作:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    targetNamespace="http://www.myexample.com/actions/data"
    xmlns:tns="http://www.myexample.com/actions/data" xmlns:command="http://www.myexample.com/command"
    elementFormDefault="qualified">
    <xs:import namespace="http://www.myexample.com/command"
        schemaLocation="../../spml-example.xsd" />

    <xs:element name="read" type="tns:readType"
        substitutionGroup="command:Action" />

    <xs:complexType name="readType">
        <xs:complexContent>
            <xs:extension base="command:ActionType">
                <xs:attribute name="a" type="xs:string"/>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

</xs:schema>

第二个是spml-local-actions.xsd,它定义了一个弹出操作:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    targetNamespace="http://www.myexample.com/actions/local"
    xmlns:tns="http://www.myexample.com/actions/local" xmlns:command="http://www.myexample.com/command"
    elementFormDefault="qualified">
    <xs:import namespace="http://www.myexample.com/command"
        schemaLocation="../../spml-example.xsd" />

    <xs:element name="popup" type="tns:PopupType"
        substitutionGroup="command:Action" />

        <xs:complexType name="PopupType">
        <xs:complexContent>
            <xs:extension base="command:ActionType" >
                <xs:attribute name="width" type="xs:float"/> 
                <xs:attribute name="height" type="xs:float"/>
                <xs:attribute name="view" type="xs:string"/>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>
</xs:schema>

请注意这些操作位于不同的命名空间

现在我创建了以下xml实例,效果很好:

<?xml version="1.0" encoding="UTF-8"?>
<Command xmlns="http://www.myexample.com/command" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:crud="http://www.myexample.com/actions/data"
    xmlns:local="http://www.myexample.com/actions/local"
    xsi:schemaLocation="http://www.myexample.com/command spml-example.xsd 
    http://www.myexample.com/actions/data actions/data/spml-test-actions.xsd 
    http://www.myexample.com/actions/local actions/local/spml-local-actions.xsd">
    <local:popup/>
</Command>

但是这里是怪癖,现在如果我添加crud:读取操作它失败并显示消息“cvc-complex-type.2.4.a:从元素'crud:read'开始发现无效内容。其中一个'{“http://  www.myexample.com/command":Action}'预计“

这并不意味着crud:read不正常,因为如果现在我将删除local:popup动作xml再次有效,即它只允许添加一个命名空间的动作。

我确实有一个解决方案,这个设计不正确,我可以添加spml-example.xsd导入的spml-test-actions.xsd和spml-local-actions.xsd。

请帮助,谢谢。

3 个答案:

答案 0 :(得分:1)

我发现了问题,如上所述。只需要进入eclipse到窗口 - &gt;喜好 然后在xml验证中取消标记复选框“荣誉所有Xml架构位置”。 看错误 - XML editor can't validate element of substitutionGroup

答案 1 :(得分:0)

它适用于我(使用Saxon-EE 9.4作为模式处理器)。它可能是架构处理器中的错误,也可能与配置它的方式有关。

答案 2 :(得分:0)

我认为您的问题中缺少的是如何验证XML;与Michael不同,我认为您的问题与架构处理器无关,而是与验证XML的方式有关。

如果您的XML编辑器或您正在使用的任何API依赖于xsi:schemaLocation提示,那么显然会发生的是它只加载第一个XML Schema文件。您可以通过从schemaLocation提示中删除http://www.myexample.com/command spml-example.xsd来轻松玩游戏;我想那会发生什么,你的替换组的成员从你第一次列出的XSD,以及从导入的那些,将工作得很好;之后的一切都不会。

如果您确实认为这是罪魁祸首,那么您可以做些什么来解决它 - 如果您希望坚持使用schemaLocation提示 - 是创建一个导入您的crud和本地XSD的XSD(忘记{{1 })并使用XSD作为提示。

否则,要获得合理的建议,您必须详细描述如何进行验证(我猜测的是基于Java的错误消息,最有可能是Xerces)。