在测试开发过程中经常遇到各种存储格式的数据转换,前面也写了几篇小文。所以这里把它整合一下。
一.python 下xml和dict相互转化,含attributes
我们写测试用例或者配置文件很多都是用xml文件来存储,但是数据要在程序中被使用,还是拿dict来用比较方便,所以有必要掌握xml转换为dict的技巧。互转程序片段如下:
from lxml import etree
def dictlist(node):
res = {}
res[node.tag] = []
xmltodict(node,res[node.tag])
reply = {}
reply[node.tag] = {'value':res[node.tag],'attributes':node.attrib}
return reply
def xmltodict(node,res):
rep = {}
if len(node):
#n = 0
for n in list(node):
rep[node.tag] = []
value = xmltodict(n,rep[node.tag])
if len(n):
value = {'value':rep[node.tag],'attributes':n.attrib}
#print value
res.append({n.tag:value})
else :
#print rep[node.tag][0]
res.append(rep[node.tag][0])
else:
value = {}
value = {'value':node.text,'attributes':node.attrib}
#print value
res.append({node.tag:value})
return
def fromstring(strdict=None):
root = etree.fromstring(strdict)
return dictlist(root)
def parse(filename=None):
tree = etree.parse(filename)
return dictlist(tree.getroot())
def main():
tree = etree.parse('test.xml')
print tree
res = dictlist(tree.getroot())
print res
def dict2xml(d):
from xml.sax.saxutils import escape
def unicodify(o):
if o is None:
return u'';
return unicode(o)
lines = ["<?xml version=/"1.0/" encoding=/"utf-8/"?>"]
def addDict(node, offset):
for name, value in node.iteritems():
if name == "attributes":
strqq = lines[len(lines)-1]
index = strqq.find(u"<")
strqq = strqq[index+1:len(strqq)-1]
for x,y in value.iteritems():
strqq = strqq + u" " *4 + u"%s='%s'"%(x,y)
lines[len(lines)-1] = u" " * index + u"<%s>"%(strqq)
else:
if isinstance(value, dict):
lines.append(offset + u"<%s>" % name)
addDict(value, offset + u" " * 4)
lines.append(offset + u"</%s>" % name)
elif isinstance(value, list):
for item in value:
if isinstance(item, dict):
addDict(item, offset + u" " * 4)
else:
lines.append(offset + u"<%s>%s</%s>" % (name, escape(unicodify(item)), name))
else:
if value != "":
pass
addDict(d, u"")
lines.append(u"")
return u"/n".join(lines)
二、利用jsoncpp将json字符串转换为Vector
在API测试过程中经常会遇到传入参数为复杂类型,一般情况下在python下,习惯用字典来表示复杂类型。但是c++对字符串的处理是比较弱智的,一般 c++里边会用vector来存储复杂类型,那么就存在转换的问题,下面小段代码记录了将字符串转换为Vector的过程
待转换的字符串如下:
const char * jsongroupinfo="[{/"groupId/" :946838524,/"groupname/" :/"bababa/", /"mask/":1,/"parentid/":946755072}]";
转换程序片段
Json::Reader reader;
Json::Value json_object;
if (!reader.parse(jsongroupinfo, json_object))
return "parse jsonstr error";
SUserChggroup sucg;
VECTOR< SUserChggroup > m_groupInfo;
for(int i = 0; i < json_object.size(); i ++)
{
Json::Value ¤t = json_object[i];
sucg.m_groupId = current["groupId"].asInt();
sucg.m_groupName = current["groupname"].asString();
sucg.m_mask = current["mask"].asInt();
sucg.m_parentId = current["parentid"].asInt();
m_groupInfo.push_back(sucg);
}
三、python中将json字符串转换为dict
首先要确认是否存在simplejson的类库,python2.6及以上版本默认自带,
python2.5需要到如下目录下载
http://pypi.python.org/packages/source/s/simplejson/simplejson-2.1.2.tar.gz#md5=a856f9ae9ab3749991a93ddeafadc554
接下来的代码如下
import simplejson
js = "{/"description/":/"fdsafsa/",/"order/":/"1/",/"place/":/"22 Plainsman Rd, Mississauga, ON, Canada/",/"lat/":43.5969175,/"lng/":-79.7248744,/"locationDate/":/"03/24/2010/"},{/"description/":/"sadfdsa/",/"order/":/"2/",/"place/":/"50 Dawnridge Trail, Brampton, ON, Canada/",/"lat/":43.7304774,/"lng/":-79.8055435,/"locationDate/":/"03/26/2010/"},"
simplejson.loads('[%s]' % js[:-1])
三行代码搞定,为什么python代码总是那么简单呢
可见python在处理结构化数据方面的能力还是相当强悍的