如何在XSD模式中要求一个元素具有一组或另一组属性?

2 投票
1 回答
898 浏览
提问于 2025-04-15 22:34

我正在处理一个XML文档,其中一个标签必须有一组属性或另一组属性。举个例子,它要么看起来像 <tag foo="hello" bar="kitty" />,要么像 <tag spam="goodbye" eggs="world" />

<root>
    <tag foo="hello" bar="kitty" />
    <tag spam="goodbye" eggs="world" />
</root>

为此,我有一个XSD模式,在里面我使用了 xs:choice 元素来选择这两组不同的属性。

<xsi:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema" attributeFormDefault="unqualified" elementFormDefault="qualified">
    <xs:element name="root">
        <xs:complexType>
            <xs:sequence>
                <xs:element maxOccurs="unbounded" name="tag">
                    <xs:choice>
                        <xs:complexType>
                            <xs:attribute name="foo" type="xs:string" use="required" />
                            <xs:attribute name="bar" type="xs:string" use="required" />
                        </xs:complexType>
                        <xs:complexType>
                            <xs:attribute name="spam" type="xs:string" use="required" />
                            <xs:attribute name="eggs" type="xs:string" use="required" />
                        </xs:complexType>
                    </xs:choice>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xsi:schema>

但是,当我使用 lxml 来加载这个模式时,我遇到了以下错误:

>>> from lxml import etree  
>>> etree.XMLSchema( etree.parse("schema_choice.xsd") )
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "xmlschema.pxi", line 85, in lxml.etree.XMLSchema.__init__ (src/lxml/lxml.etree.c:118685)
lxml.etree.XMLSchemaParseError: Element '{http://www.w3.org/2001/XMLSchema}element': The content is not valid. Expected is (annotation?, ((simpleType | complexType)?, (unique | key | keyref)*))., line 7

因为错误出在我的 xs:choice 元素的位置上,我尝试把它放在不同的地方,但无论我怎么尝试,我似乎都无法用它来定义一个标签,使其拥有一组属性(foobar)或另一组属性(spameggs)。

这真的可能吗?如果可以的话,正确的语法是什么?

1 个回答

5

很遗憾,在XML模式中,不能把选择和属性一起使用。你需要在更高的层面上来实现这种验证。

撰写回答