soapergem
soapergem

Reputation: 10019

How do I create a namespaced element with lxml?

I'm using lxml to generate an RSS feed that is ultimately used as a podcast. That means I need to add namespaced elements like <itunes:duration> and <itunes:subtitle>. But I'm having so much trouble trying to figure out how to create elements like these with lxml dynamically.

If I simply try:

from lxml import etree

element = etree.Element("itunes:duration")

I get this:

ValueError: Invalid tag name 'itunes:duration'

Next I tried this and got a little closer:

from lxml import etree

etree.register_namespace("itunes", "http://www.itunes.com/dtds/podcast-1.0.dtd")
element = etree.Element("{itunes}duration")
print(etree.tostring(element).decode("utf-8"))

However that resulted in this output:

<ns0:duration xmlns:ns0="itunes"/>

So while that's better than an exception, it's still obviously not right. How can I create an element with an itunes: prefix in the tag name?

Upvotes: 3

Views: 3680

Answers (1)

Daniel Haley
Daniel Haley

Reputation: 52878

Try using etree.QName()...

from lxml import etree

etree.register_namespace("itunes", "http://www.itunes.com/dtds/podcast-1.0.dtd")
element = etree.Element(etree.QName("http://www.itunes.com/dtds/podcast-1.0.dtd", "duration"))
print(etree.tostring(element).decode("utf-8"))

prints...

<itunes:duration xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"/>

You could also just use Clark notation...

element = etree.Element("{http://www.itunes.com/dtds/podcast-1.0.dtd}duration")

Upvotes: 7

Related Questions