我正在尝试使用lxml创建XML Schema。对于这样的开头:
<xs:schema xmlns="http://www.goo.com" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://www.goo.com">
<xs:element type="xs:string" name="name"/>
<xs:element type="xs:positiveInteger" name="age"/>
</xs:schema>
我这样做了 - 通过puts xs:在值之前,但我认为它可以做得更好。
def schema():
SCHEMA_NAMESPACE = "http://www.w3.org/2001/XMLSchema"
XS = "{%s}" % SCHEMA_NAMESPACE
NSMAP = {None: "http://www.goo.com"}
schema = etree.Element(XS+"schema",
nsmap = NSMAP,
targetNamespace="http://www.goo.com",
elementFormDefault="qualified")
element = etree.Element(XS+"element",
attrib = {"name" : "name",
"type" : "xs:string"})
schema.append(element)
element = etree.Element(XS+"element",
attrib = {"name" : "age",
"type" : "xs:positiveInteger"})
schema.append(element)
return etree.tostring(schema, pretty_print=True)
可以用某种方式更好地写出来吗?
答案 0 :(得分:2)
除此之外,您需要在NSMAP中包含"xs": SCHEMA_NAMESPACE
等 - 否则生成的XML中的任何内容都不会将'xs'前缀映射到正确的命名空间。这也允许您只使用前缀指定元素名称;例如“XS:元素”
就您的主要问题而言,我认为这可能没问题,只要您始终在所有地方使用相同的前缀到命名空间映射,例如使用全局NSMAP
。如果您正在处理具有可能任意名称空间前缀的XML,请确保:
nsmap
添加到您创建的每个元素中;或_Element.nsmap
属性获取父属性的命名空间映射,将其反转,并在反转映射中查找相应的前缀。后者的一个例子:
SCHEMA_NAMESPACE = "http://www.w3.org/2001/XMLSchema"
def add_element(schema):
nsmap = schema.nsmap
nsrmap = dict([(uri, prefix) for prefix, uri in nsmap.items()])
prefix = nsrmap[SCHEMA_NAMESPACE]
xs = lambda name: "%s:%s" % (prefix, name)
element = schema.makeelement(xs("element"), nsmap=nsmap,
attrib={'name': 'age', 'type': xs('string')})
schema.append(element)
return etree.tostring(schema, pretty_print=True)
但对于大多数情况来说,这可能有点过分了。