如何使用lxml在属性值中设置名称空间前缀?

时间:2010-09-10 14:24:05

标签: python namespaces lxml prefix

我正在尝试使用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)

可以用某种方式更好地写出来吗?

1 个答案:

答案 0 :(得分:2)

除此之外,您需要在NSMAP中包含"xs": SCHEMA_NAMESPACE等 - 否则生成的XML中的任何内容都不会将'xs'前缀映射到正确的命名空间。这也允许您只使用前缀指定元素名称;例如“XS:元素”

就您的主要问题而言,我认为这可能没问题,只要您始终在所有地方使用相同的前缀到命名空间映射,例如使用全局NSMAP。如果您正在处理具有可能任意名称空间前缀的XML,请确保:

  • 将您带有'xs'前缀的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)

但对于大多数情况来说,这可能有点过分了。