Akshay Upadhyaya
Akshay Upadhyaya

Reputation: 11

How do I add attributes to elements with ElementMaker?

I have to generate an XML as below,

<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<serviceConfiguration xmlns="http://blah.com/serviceConfiguration">
  <node name="node1">
    <hostName>host1</hostName>
    <networkInterface name="eth0">
      <ipv4Address>192.168.1.3</ipv4Address>
      <ipv6Address>2a00:4a00:a000:11a0::a4f:3</ipv6Address>
      <domainName>asdf.net</domainName>
      <ipv4Netmask>255.255.255.0</ipv4Netmask>
      <ipv6Netmask>ffff:ffff:ffff:ffff::</ipv6Netmask>
    </networkInterface>
    <userAccount>
      <uid>root</uid>
      <uidNumber>0</uidNumber>
      <gidNumber>0</gidNumber>
      <homeDirectory>/root</homeDirectory>
      <publicKey>
        <key/>
        <algorithm>RSA</algorithm>
      </publicKey>
      </userAccount>
  </node>
</serviceConfiguration>

The code I have been trying (below) generates all things fine but I am not able to set attributes value for node and network interface. I need <node name="node1"> instead of <node> and <networkInterface name="eth0"> instead of <networkInterface>. I tried adding attributes in bracket for node and network interface but python doesn't seem to take it.

ElementMaker does not take attributes passed to head. What would be the appropriate syntax to do that? How is it possible to achieve?

Code:

from lxml import etree
from lxml.builder import ElementMaker

E = ElementMaker(namespace="http://blah.com/serviceConfiguration", nsmap={None: "http://blah.com/serviceConfiguration"})

SC = E.serviceConfiguration
NODE = E.node
HN = E.hostName
NI = E.networkInterface
I4 = E.ipv4Address
I6 = E.ipv6Address
DN = E.domainName
I4N = E.ipv4Netmask
I6N = E.ipv6Netmask
UA = E.userAccount
UI = E.uid
UIN = E.uidNumber
GIN = E.gidNumber
HD = E.homeDirectory
PK = E.publicKey
K = E.key
A = E.algorithm

my_doc = SC(
      NODE(
        HN('host1'),
        NI(
          I4('ipv4Address'),
          I6('ipv6Address'),
          DN('domainName'),
          I4N('ipv4Netmask'),
          I6N('ipv6Netmask')
          ),
        UA(
          UI('uid'),
          UIN('uidNumber'),
          GIN('gidNumber'),
          HD('homeDirectory'),
          PK(
            K('key'),
            A('algorithm')
            )
          )
        )
      )

print(etree.tostring(my_doc, encoding="UTF-8", standalone="yes", pretty_print=True))

Upvotes: 1

Views: 1086

Answers (1)

mzjn
mzjn

Reputation: 50947

Add the attributes as keyword arguments after the subelements:

my_doc = SC(
    NODE(
        HN('host1'),
        NI(
            I4('ipv4Address'),
            I6('ipv6Address'),
            DN('domainName'),
            I4N('ipv4Netmask'),
            I6N('ipv6Netmask'),
            name="eth0"),
        UA(
            UI('uid'),
            UIN('uidNumber'),
            GIN('gidNumber'),
            HD('homeDirectory'),
            PK(
                K('key'),
                A('algorithm')
            )
          ),
          name="node1")
)

Or provide the attributes via a dictionary:

my_doc = SC(
    NODE({'name': 'node1'},
        HN('host1'),
        NI(
            I4('ipv4Address'),
            I6('ipv6Address'),
            DN('domainName'),
            I4N('ipv4Netmask'),
            I6N('ipv6Netmask'),
            name="eth0"),
        UA(
            UI('uid'),
            UIN('uidNumber'),
            GIN('gidNumber'),
            HD('homeDirectory'),
            PK(
                K('key'),
                A('algorithm')
            )
        )
     )
)

Upvotes: 1

Related Questions