如何使用ElementMaker向元素添加属性?

时间:2017-11-10 09:52:42

标签: python xml lxml

我必须生成如下的XML,

<?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>

我一直在尝试的代码(下面)生成所有东西,但是我无法为节点和网络接口设置属性值。 我需要<node name="node1">而不是<node><networkInterface name="eth0">而不是<networkInterface>。我尝试在节点和网络接口的括号中添加属性,但python似乎没有采取它。

ElementMaker不会将传递给头部的属性。这样做的合适语法是什么?怎么可能实现?

代码:

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))

1 个答案:

答案 0 :(得分:1)

在子元素之后添加属性作为关键字参数:

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")
)

或通过字典提供属性:

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')
            )
        )
     )
)