Python XML点名称构造

2024-06-25 23:52:04 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个solacejms消息传递框,我正在自动管理它,并且设备使用许多非常小的XML帖子来配置。由于设备的XML规范中有很多命令,我需要一种方法来创建任意的XML请求。在

XML看起来像:

<rpc semp-version="soltr/5_5">
<create>
<message-vpn>
<vpn-name>developer.testvpn</vpn-name>
</message-vpn>
</create>
</rpc>

第二次调用以更改设置可能如下所示:

^{pr2}$

由于XML规范中有许多命令,所以我正在寻找一种从点名称空间等自由创建命令的方法。例如:

mycall = SolaceXML()
mycall.create.message_vpn.vpn_name="developer.testvpn"
mycall.message_vpn.vpn_name='developer.testvpn'
mycall.message_vpn.export_policy.no.export_subscription

更新 我已经在下面公布了我的解决方案。它没有我想要的那么小,但它对我有用。在

K


Tags: 方法name命令规范developermessagecreateexport
1条回答
网友
1楼 · 发布于 2024-06-25 23:52:04

同时我也找到了解决办法。希望这对其他人有帮助。此解决方案从点名称空间调用构建嵌套字典对象,然后将其转换为XML。在

from xml.dom.minidom import Document
import copy
import re
from collections import OrderedDict

class d2x:
    ''' Converts Dictionary to XML '''
    def __init__(self, structure):
        self.doc = Document()
        if len(structure) == 1:
            rootName = str(structure.keys()[0])
            self.root = self.doc.createElement(rootName)
            self.doc.appendChild(self.root)
            self.build(self.root, structure[rootName])

    def build(self, father, structure):
        if type(structure) == dict:
            for k in structure:
                tag = self.doc.createElement(k)
                father.appendChild(tag)
                self.build(tag, structure[k])
        elif type(structure) == OrderedDict:
            for k in structure:
                tag = self.doc.createElement(k)
                father.appendChild(tag)
                self.build(tag, structure[k])

        elif type(structure) == list:
            grandFather = father.parentNode
            tagName = father.tagName
            grandFather.removeChild(father)
            for l in structure:
                tag = self.doc.createElement(tagName)
                self.build(tag, l)
                grandFather.appendChild(tag)

        else:
            data = str(structure)
            tag = self.doc.createTextNode(data)
            father.appendChild(tag)

    def display(self):
        # I render from the root instead of doc to get rid of the XML header
        #return self.root.toprettyxml(indent="  ")
        return self.root.toxml()

class SolaceNode:
    ''' a sub dictionary builder '''
    def __init__(self):
        self.__dict__ = OrderedDict()
    def __getattr__(self, name):
        name = re.sub("_", "-", name)
        try:
            return self.__dict__[name]
        except:
            self.__dict__[name] = SolaceNode()
            return self.__dict__[name]
    def __str__(self):
        return str(self.__dict__)
    def __repr__(self):
        return str(self.__dict__)
    def __call__(self, *args, **kwargs):
        return self.__dict__
    def __setattr__(self, name, value):
        name = re.sub("_", "-", name)
        self.__dict__[name] = value

class SolaceXMLBuilder(object):
    ''' main dictionary builder

    Any dot-name-space like calling of a instance of SolaceXMLBuilder will create
    nested dictionary keys. These are converted to XML whenever the instance 
    representation is called ( __repr__ ) 

    Example

    a=SolaceXMLBuilder()
    a.foo.bar.baz=2
    str(a)
    '<rpc semp-version="soltr/5_5">\n<foo><bar><baz>2</baz></bar></foo></rpc>'

    '''
    def __init__(self):
        self.__dict__ = OrderedDict()
        self.__setattr__ = None
    def __getattr__(self, name):
        name = re.sub("_", "-", name)
        try:
            return self.__dict__[name]
        except:
            self.__dict__[name] = SolaceNode()
            return self.__dict__[name]
    def __repr__(self):
        # Show XML
        myxml = d2x(eval(str(self.__dict__)))
        # I had to conjur up my own header cause solace doesnt like </rpc> to have attribs
        #return str('<rpc semp-version="soltr/5_5">\n%s</rpc>' % myxml.display())
        return str('<rpc semp-version="soltr/5_5">\n%s</rpc>' % myxml.display())
    def __call__(self, *args, **kwargs):
        return self.__dict__
    # def __setattr__(self, name, value):
    #   raise Exception('no you cant create assignments here, only on sub-elements')



if __name__ == '__main__':
    x = SolaceXMLBuilder()
    x.create.message_vpn.vpn_name='NEWVPN'
    print(x)

    # <?xml version="1.0" ?>
    # <rpc semp-version="soltr/5_5">
    #   <create>
    #     <message-vpn>
    #       <vpn-name>
    #         NEWVPN
    #       </vpn-name>
    #     </message-vpn>
    #   </create>
    # </rpc semp-version="soltr/5_5">   

    x=SolaceXMLBuilder()
    x.message_vpn.vpn_name='NEWVPN'
    x.message_vpn.no.feature_X
    print(x)

    # <?xml version="1.0" ?>
    # <rpc semp-version="soltr/5_5">
    #   <message-vpn>
    #     <vpn-name>
    #       NEWVPN
    #     </vpn-name>
    #     <no>
    #       <feature-X/>
    #     </no>
    #   </message-vpn>
    # </rpc semp-version="soltr/5_5">


    # >>> client = SolaceAPI('pt1')
    # >>> xml = SolaceXMLBuilder()
    # >>> xml.create.message_vpn.vpn_name='NEWVPN'
    # >>> client.rpc(str(xml))
    # {u'rpc-reply': {u'execute-result': {u'@code': u'ok'}, u'@semp-version': u'soltr/5_5'}}

相关问题 更多 >