Todd Vanyo
Todd Vanyo

Reputation: 593

lxml ElementMaker Attribute formatting

Thanks to this question/answer, I was able to get a namespace attribute added to a root element. So now I have this:

Code

from lxml.builder import ElementMaker

foo = 'http://www.foo.org/XMLSchema/bar'
xsi = 'http://www.w3.org/2001/XMLSchema-instance'
E = ElementMaker(namespace=foo, nsmap={'foo': foo, 'xsi': xsi})

fooroot = E.component()
fooroot.attrib['{{{pre}}}schemaLocation'.format(pre=xsi)] = 'http://www.foo.org/XMLSchema/bar http://www.foo.org/XMLSchema/barindex.xsd'
bars = E.bars(label='why?', validates='required')
fooroot.append(bars)
bars.append(E.bar(label='Image1'))
bars.append(E.bar(label='Image2'))

etree.dump(fooroot)

This give me the desired output:

Output

<foo:component xmlns:foo="http://www.foo.org/XMLSchema/bar" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.foo.org/XMLSchema/bar http://www.foo.org/XMLSchema/barindex.xsd">
  <foo:bars label="why?" validates="required">
    <foo:bar label="Image1"/>
    <foo:bar label="Image2"/>
  </foo:bars>
</foo:component>

The question

Why does the fooroot.attrib['{{{pre}}}schemaLocation'.format(pre=xsi)] require 3 braces around the pre?

1 brace: {pre} causes a ValueError BAD
2 braces: {{pre}} produces ns0:schemaLocation on the output BAD
3 braces: {{{pre}}} produces xsi:schemaLocation on the output GOOD

I understand the .format usage for the string, but I'd like to understand why I need 3 braces.

Upvotes: 3

Views: 1652

Answers (1)

har07
har07

Reputation: 89285

The format of namespaced attribute name in lxml is {namespace-uri}local-name. So for xsi:schemaLocation, you basically want to add attribute with name:

'{http://www.w3.org/2001/XMLSchema-instance}schemaLocation'

The {namespace-uri} part can be achieved using format() and the triple opening and closing braces which can be read as:

  • {{: escaped opening braces; outputs literal {
  • {pre}: placeholder; will be replaced by the value of variable xsi as specified in .format(pre=xsi)
  • }}: escaped closing braces; outputs literal }

Upvotes: 5

Related Questions