How to add a namespace to an attribute in lxml

2019-02-21 14:41发布

问题:

I'm trying to create an xml entry that looks like this using python and lxml:

<resource href="Unit 4.html" adlcp:scormtype="sco">

I'm using python and lxml. I'm having trouble with the adlcp:scormtype attribute. I'm new to xml so please correct me if I'm wrong. adlcp is a namespace and scormtype is an attribute that is defined in the adlcp namespace, right?
I'm not even sure if this is the right question but... My question is, how do I add an attribute to an element from a non-default namespace using lxml? I apologize in advance if this is a trivial question.

回答1:

This is not a full reply but just a few pointers.

adlcp is not the namespace it is a namespace prefix. The namespace is defined in the document by an attribute like xmlns:adlcp="http://xxx/yy/zzz"

In lxml you always set an element/attribute name including the namespace e.g. {http://xxx/yy/zzz}scormtype instead of just scormtype. lxml will then put in a namespace prefix automatically. However lxml will set the prefix to ns0 or similar unless you do more fiddling but that should be sufficient as the prefix does not mean anything. (However some people prefer controlling the prefix name; see the nsmap argument on the Element and SubElement functions, and the register_namespace function).

I would look at the lxml tutorial on namespace and also Dive into Python - XML chapter



回答2:

Try this:

builder = ElementMaker(namespace="http://a.different.url/blah/v.10",
                       nsmap={
                         'adlcp': "http://a.namespace.url/blah/v.10",
                         'anotherns': "http://a.different.url/blah/v.10"
                       })

builder.resource()
builder.attrib['href'] = "Unit 4.html"
builder.attrib['{http://a.namespace.url/blah/v.10}scormtype'] = 'sco'

print(etree.tostring(builder, pretty_print=True))