]> git.evergreen-ils.org Git - OpenSRF.git/blob - src/python/osrf/utils.py
1d9d7aaa3608c59e312145eb29f3e06299eacd93
[OpenSRF.git] / src / python / osrf / utils.py
1 # -----------------------------------------------------------------------
2 # Copyright (C) 2007  Georgia Public Library Service
3 # Bill Erickson <billserickson@gmail.com>
4
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License
7 # as published by the Free Software Foundation; either version 2
8 # of the License, or (at your option) any later version.
9
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 # -----------------------------------------------------------------------
15
16 import libxml2, re
17
18 def osrfXMLFileToObject(filename):
19         """Turns the contents of an XML file into a Python object"""
20         doc     = libxml2.parseFile(filename)
21         xmlNode = doc.children.children
22         return osrfXMLNodeToObject(xmlNode)
23
24 def osrfXMLStringToObject(string):
25         """Turns an XML string into a Python object"""
26         doc     = libxml2.parseString(string)
27         xmlNode = doc.children.children
28         return osrfXMLNodeToObject(xmlNode)
29
30 def osrfXMLNodeToObject(xmlNode):
31         """Turns an XML node into a Python object"""
32         obj = {}
33
34         while xmlNode:
35                 if xmlNode.type == 'element':
36                         nodeChild = xmlNode.children
37                         done = False
38                         nodeName = xmlNode.name
39
40                         while nodeChild:
41                                 if nodeChild.type == 'element':
42
43                                         # If a node has element children, create a new sub-object 
44                                         # for this node, attach an array for each type of child
45                                         # and recursively collect the children data into the array(s)
46
47                                         if not obj.has_key(nodeName):
48                                                 obj[nodeName] = {}
49
50                                         sub_obj = osrfXMLNodeToObject(nodeChild);
51
52                                         if not obj[nodeName].has_key(nodeChild.name):
53                                                 # we've encountered 1 sub-node with nodeChild's name
54                                                 obj[nodeName][nodeChild.name] = sub_obj[nodeChild.name]
55
56                                         else:
57                                                 if isinstance(obj[nodeName][nodeChild.name], list):
58                                                         # we already have multiple sub-nodes with nodeChild's name
59                                                         obj[nodeName][nodeChild.name].append(sub_obj[nodeChild.name])
60
61                                                 else:
62                                                         # we already have 1 sub-node with nodeChild's name, make 
63                                                         # it a list and append the current node
64                                                         val = obj[nodeName][nodeChild.name]
65                                                         obj[nodeName][nodeChild.name] = [ val, sub_obj[nodeChild.name] ]
66
67                                         done = True
68
69                                 nodeChild = nodeChild.next
70
71                         if not done:
72                                 # If the node has no children, clean up the text content 
73                                 # and use that as the data
74                                 data = re.compile('^\s*').sub('', xmlNode.content)
75                                 data = re.compile('\s*$').sub('', data)
76
77                                 obj[nodeName] = data
78
79                 xmlNode = xmlNode.next
80
81         return obj
82
83
84 def osrfObjectFindPath(obj, path, idx=None):
85         """Searches an object along the given path for a value to return.
86
87         Path separaters can be '/' or '.', '/' is tried first."""
88
89         parts = []
90
91         if re.compile('/').search(path):
92                 parts = path.split('/')
93         else:
94                 parts = path.split('.')
95
96         for part in parts:
97                 try:
98                         o = obj[part]
99                 except Exception:
100                         return None
101                 if isinstance(o,str): 
102                         return o
103                 if isinstance(o,list):
104                         if( idx != None ):
105                                 return o[idx]
106                         return o
107                 if isinstance(o,dict):
108                         obj = o
109                 else:
110                         return o
111
112         return obj
113
114
115                         
116