XML验证:验证URI类型

2 投票
1 回答
2624 浏览
提问于 2025-04-16 02:08

我正在使用Python的lxml库来验证XML文件是否符合一个模式(schema)。我有一个模式,其中包含一个元素:

<xs:element name="link-url" type="xs:anyURL"/>

然后我测试,比如说,这段XML的一部分:

<a link-url="server/path"/>

我希望这个测试失败,因为这个link-url没有以http://开头。我试着把anyURI换成anyURL,但这样会导致一个错误——这不是一个有效的标签。

用lxml做到这一点可能吗?在模式验证中,这种情况有可能吗?

1 个回答

3

(我很确定 xs:anyURL 这个写法是不对的。根据 XML Schema 标准,正确的写法应该是 anyURI。而且因为 link-url 是一个属性,你应该用 xs:attribute 而不是 xs:element 来定义它,对吧?)

你可以通过创建一个新的 simpleType 来限制这些网址,然后在这个类型上加一个 restriction 来限制它的 pattern。比如说,

#!/usr/bin/env python2.6

from lxml import etree
from StringIO import StringIO

schema_doc = etree.parse(StringIO('''
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xs:simpleType name="httpURL">
        <xs:restriction base="xs:anyURI">
            <xs:pattern value='https?://.+'/>
            <!-- accepts only http:// or https:// URIs. -->
        </xs:restriction>
    </xs:simpleType>

    <xs:element name="a">
        <xs:complexType>
            <xs:attribute name="link-url" type="httpURL"/>
        </xs:complexType>
    </xs:element>
    </xs:schema>
''')) #/
schema = etree.XMLSchema(schema_doc)

schema.assertValid(etree.parse(StringIO('<a link-url="http://sd" />')))
assert not schema(etree.parse(StringIO('<a link-url="server/path" />')))

撰写回答