XMLããªã¼ã®ã¿ã°ã¸ã®åç §ãå±æ§ã¢ã¯ã»ã¹ã§å®ç¾ãã
Pythonã§XMLãèªãã§è¾æ¸ãªãã¸ã§ã¯ãã®æ¨ã«å¤æããããã°ã©ã ãæ¸ãããã©ãªããããã¦ãªãã®ã§ãã¿ã°ã¸ã®ã¢ã¯ã»ã¹ãå±æ§ã¢ã¯ã»ã¹ã§å®ç¾ããæ¹æ³ãèãã¦ã¿ã¾ãããè¦ã¯
<root> <children> <child>A</child> <child>B</child> <child>C</child> <child>D</child> </children> </root>
ããããXMLãèªãã§ãPythonãã
root['children']['child'][0]
ããã¢ã¯ã»ã¹ã§ããããã«ãããã©ãããã«æãå ãã¦
root.children.child[0]
ããæ¸ãããã
Pythonã§ã¯ã__getattr__ã¨__setattr__ããªã¼ãã¼ã©ã¤ããããã¨ã§ããªãã¸ã§ã¯ãã«å¯¾ããå±æ§ã¢ã¯ã»ã¹ã®æåãå¤æ´ã§ãã¾ãã
3.4.2 å±æ§å¤ã¢ã¯ã»ã¹ãã«ã¹ã¿ãã¤ãºãã
åèï¼Pythonã®ã¯ã©ã¹ã·ã¹ãã
class A(object): def __init__(self): self.lst = ['alice', 'bob', 'carol'] def __getattr__(self, name): if name[:2] == 'at': return self.lst[int(name[2:])] return self.__dict__[name] def __setattr__(self, name, value): if name[:2] == 'at': self.lst[int(name[2:])] = value self.__dict__[name] = value a = A() print a.lst # => ['alice', 'bob', 'carol'] print a.at0 # => 'alice' print a.at1 # => 'bob' a.at1 = 'bump' print a.at1 # => 'bump'
ãããå©ç¨ãã¦ãå±æ§ã«ã¢ã¯ã»ã¹ãããæã«åãã¼ããæ¢ç´¢ã対å¿ãããªãã¸ã§ã¯ããè¿ãã¦ãã¿ã°åã«ããå±æ§ã¢ã¯ã»ã¹ãå¯è½ã«ãã¾ãããã®ãããªã¯ã©ã¹ãNodeã¯ã©ã¹ã¨ãã¦ãã¿ã°åç §ã®çµæã¨ãã¦æ»ãå¤ã常ã«Nodeã¯ã©ã¹ã¾ãã¯ããªããã£ãåã¨ããã°ãa.b.cã®ããã«ã©ãã©ãæ¨ãä¸ã«ä¸ãã¦ãããã¨ãã§ããã¯ãã§ãã
以ä¸ã®ããã°ã©ã ã½ã¼ã¹ãlibxmlload.pyã¨ãããã¡ã¤ã«åã§ä¿åãã¾ãã
# coding: utf-8 import urllib from xml.etree.ElementTree import * class Node(object): def __init__(self, name, info): self.__dict__['_info'] = info self.__dict__['_name'] = name def __getattr__(self, name): if name in self.__dict__['_info']: return self.__dict__['_info'][name] return self.__dict__[name] def __setattr__(self, name, value): self.__dict__['_info'][name] = value; def __iter__(self): return self._info.iteritems() def __repr__(self): args = self._name, ','.join(self._info.keys()) return "<%s keys=%s>" % args def xmltrans(xmlnode): node = Node(xmlnode.tag, {}) for child in xmlnode: key = child.tag if len(child) == 0: val = child.text if val is not None: val = val.strip() assign(node._info, key, val) else: assign(node._info, key, xmltrans(child)) return node def assign(info, key, value): if key in info: if isinstance(info[key], list): info[key].append(value) else: info[key] = [info[key], value] else: info[key] = value def urlopen(url): # http access conn = urllib.urlopen(url) xmlstr = conn.read() # create xml xmldoc = fromstring(xmlstr) # xml to object tree otree = xmltrans(xmldoc) return otree def parse(filepath): fobj = open(filepath) xmlstr = fobj.read() xmldoc = fromstring(xmlstr) otree = xmltrans(xmldoc) return otree
XMLãã¡ã¤ã«ãèªã¿è¾¼ãã§ã¿ã¾ãã
ã¾ããä¸ã®XMLãtest.xmlã¨ãã¦ä¿åãã¾ãã
<root> <state>0</state> <timestamp>1234567890</timestamp> <userlist> <user> <name>A</name> <lang>Japanese</lang> </user> <user> <name>B</name> <lang>Swedish</lang> </user> <user> <name>C</name> <lang>English</lang> </user> <user> <name>D</name> <lang>French</lang> </user> <user> <name>E</name> <lang>Chinese</lang> </user> </userlist> </root>
次ã«ã¤ã³ã¿ããªã¿ããXMLãã¡ã¤ã«ãèªã¿è¾¼ã¿ã¾ãã
$ python >>> import libxmlload >>> root = libxmlload.parse('test.xml') >>> root.timestamp '1234567890' >>> root.state '0' >>> root.userlist <userlist keys=user> >>> root.userlist.user [<user keys=lang,name>, <user keys=lang,name>, <user keys=lang,name>, <user keys=lang,name>, <user keys=lang,name>] >>> root.userlist.user[0].name 'A' >>> map(lambda usr:usr.name, root.userlist.user) ['A', 'B', 'C', 'D', 'E'] >>> map(lambda usr:usr.lang, root.userlist.user) ['Japanese', 'Swedish', 'English', 'French', 'Chinese'] >>>
XMLãã¼ãã¸ã®ã¢ã¯ã»ã¹ãå±æ§ã¢ã¯ã»ã¹ã§å®ç¾ã§ãã¦ããã®ããããã¾ãã
ãã®ããã°ã©ã ã§ã¯ãã®ã»ãããããã¯ã¼ã¯ä¸ãããã¡ã¤ã«ãæã£ã¦ããé¢æ°urlopenãå®ç¾©ãã¾ããã
æå¾ã«ãããã使ã£ã¦TwitterAPIã®public_timelineããã¤ã¶ãããåå¾ãã¦ã¿ã¾ãã
$ python >>> import libxmlload >>> statuses = libxmlload.urlopen('http://api.twitter.com/1/statuses/public_timeline.xml') >>> statuses <statuses keys=status> >>> len(statuses.status) 20 >>> statuses.status[0] <status keys=favorited,contributors,truncated,text,created_at,retweeted,coordinates,source,in_reply_to_status_id,in_reply_to_screen_name,in_reply_to_user_id,place,retweet_count,geo,id,user> >>> for s in statuses.status: ... print s.user.screen_name ... pcgirl65 Xornvestite windsurfingnews co2levels _SOCIAIS_ Bedford76021 Pamposa04 Rachhh_xo kiyoohara iyodenden m0n3y_bag5 VisaVis_theater cordies_ AARTYinc babygr33ney3s mai_geek manoelagnoronha SaSSy_AsH SuperRenatoo _thaisrawr >>>