因此,我通过API从一个vShield管理器中检索数据,并构建一个数据库来与另一个数据库同步.我正在成功地从API (yay)中提取XML,我可以很好地解析它,但这有点乏味。我试图为vShield中的各种对象(虚拟防火墙、全局地址对象、服务定义等)创建自定义类。所以我可以以一种正常的方式引用我的脚本中的数据,这就是我遇到一个问题(某种程度上).
我得到的xml看起来是这样的:
<?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进行了如下操作:
# 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)在其中,我使用以下类定义:
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”一遍又一遍.
我想做这样的事情:
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给出的答案。干杯伙计!
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发布于 2015-06-12 13:00:03
像这样的东西怎么样?这基本上就是你在做的“我想做……”举例说明。scope对象上的属性默认为None,然后使用属性/xpath字典xmlPaths进行设置。您的代码中有些事情我不确定(例如,我不知道您在用locals()做什么),但我认为这是您想做的事情。
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 scopeObjectshttps://stackoverflow.com/questions/30801660
复制相似问题