首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >XML到自定义类

XML到自定义类
EN

Stack Overflow用户
提问于 2015-06-12 11:13:09
回答 1查看 690关注 0票数 0

因此,我通过API从一个vShield管理器中检索数据,并构建一个数据库来与另一个数据库同步.我正在成功地从API (yay)中提取XML,我可以很好地解析它,但这有点乏味。我试图为vShield中的各种对象(虚拟防火墙、全局地址对象、服务定义等)创建自定义类。所以我可以以一种正常的方式引用我的脚本中的数据,这就是我遇到一个问题(某种程度上).

我得到的xml看起来是这样的:

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<scopingObjects>
  <object>
    <objectId>datacenter-2</objectId>
    <type>
      <typeName>Datacenter</typeName>
    </type>
    <name>virtualDataCenter-01</name>
    <revision>5</revision>
    <objectTypeName>Datacenter</objectTypeName>
    <scope>
      <id>group-d1</id>
      <objectTypeName>Folder</objectTypeName>
      <name>Datacenters</name>
    </scope>
    <extendedAttributes/>
  </object>
  <object>
    <objectId>globalroot-0</objectId>
    <type>
      <typeName>GlobalRoot</typeName>
    </type>
    <name>Global</name>
    <revision>460</revision>
    <objectTypeName>GlobalRoot</objectTypeName>
    <extendedAttributes/>
  </object>
</scopingObjects>

我使用ElementTree进行了如下操作:

代码语言:javascript
复制
# Get the list of scoping objects
scopeObjects = [] # Declare an empty list
r = sendRest("getScopes")
xml = et.fromstring( r.text )
for object in xml.iter("object"):
    try:
        o = scope()
        o.create(et.tostring(object))
        scopeObjects.append(o)
    except Exception, e:
        print "Exception: " + repr(e)

在其中,我使用以下类定义:

代码语言:javascript
复制
class scope:
    def __init__(self):
        self.id = ""
        self.name = ""
        self.type = ""
    def create(self, xmlString):
        try:
            xml = et.fromstring(xmlString)
            if xml.find("objectId") is not None: self.id = xml.find("objectId").text
            if xml.find("name") is not None: self.name = xml.find("name").text
            if xml.find("type/typeName") is not None: self.type = xml.find("type/typeName").text
        except:
            print "Error constructing scope object from:\n%s" % xmlString
            return False

一切都是一种享受..。直到我遇到更复杂的XML结构..。然后是"if xml.find(blah/blah/blah“)不是空的狂欢:变量= xml.find("blah/blah/blah").text”一遍又一遍.

我想做这样的事情:

代码语言:javascript
复制
class scope:
  def __init__(self):
    self.id = ""
    self.name = ""
    self.type = ""
  def create(self, xmlString):
    xmlPaths = { "id" : "objectId", "name" : "name", "type" : "type/typeName" }
    for key in xmlPaths.keys():
      element = xml.find(xmlPaths[key])
      if element is not None:
        # Set the class property named by "key" to the value of element.text
        locals()[key] = element.text
        # For example, if the key is "id", then it sets "self.id" to the text of the element in XML tag "<objectId>"

基本上,我想在构造对象的时候懒惰.我不想输入大量的"if xml.“。当我开始处理API返回的更复杂的对象时,它将变得更加重要,因为有许多元素需要处理。

我的基本问题是:做这件事最好的方法是什么?

干杯!

我的解决方案:

感谢Larsks给出的答案。干杯伙计!

代码语言:javascript
复制
class scope:
    xmlPathMap = {
        "id" : "objectId",
        "name" : "name",
        "type" : "type/typeName"
    }
    def __init__(self, element):
        self.element = element
        self.create()
    def create(self):
        try:
            for key, path in self.xmlPathMap.items():
                res = self.element.find(path)
                if res is not None:
                    setattr(self, key, res.text)
        except:
            print "Error constructing scope object:\n\tkey: %s\n\tpath: %s\n\tvalue: %s" % (key, path, res.text)
            return False
# End of scope class definition
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-06-12 13:00:03

像这样的东西怎么样?这基本上就是你在做的“我想做……”举例说明。scope对象上的属性默认为None,然后使用属性/xpath字典xmlPaths进行设置。您的代码中有些事情我不确定(例如,我不知道您在用locals()做什么),但我认为这是您想做的事情。

代码语言:javascript
复制
from lxml import etree


class scope(object):
    xmlPaths = {'id': 'objectId',
                'name': 'name',
                'type': 'type/typeName'}

    def __init__(self, element):
        self.id = None
        self.name = None
        self.type = None
        self.element = element

        self.parse()

    def parse(self):
        for attr, path in self.xmlPaths.items():
            res = self.element.xpath(path)
            if res:
                setattr(self, attr, res[0].text)

    def __repr__(self):
        return '<scope id=%s name=%s type=%s>' % (
            self.id, self.name, self.type)


  with open('data.xml') as fd:
      doc = etree.parse(fd)

  scopeObjects = []
  for object in doc.iter('object'):
      o = scope(object)
      scopeObjects.append(o)

  print scopeObjects
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30801660

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档