]> git.frykholm.com Git - friends.git/blob - friends/rd/xrd.py
Some xml fixes, added rd library
[friends.git] / friends / rd / xrd.py
1
2 from xml.dom.minidom import getDOMImplementation, parseString, Node
3
4 from rd.core import RD, Element, Link, Property, Title
5
6 XRD_NAMESPACE = "http://docs.oasis-open.org/ns/xri/xrd-1.0"
7
8
9 def _get_text(root):
10 text = ''
11 for node in root.childNodes:
12 if node.nodeType == Node.TEXT_NODE and node.nodeValue:
13 text += node.nodeValue
14 else:
15 text += _get_text(node)
16 return text.strip() or None
17
18
19 def loads(content):
20
21 import isodate
22
23 def expires_handler(node, obj):
24 obj.expires = isodate.parse_datetime(_get_text(node))
25
26 def subject_handler(node, obj):
27 obj.subject = _get_text(node)
28
29 def alias_handler(node, obj):
30 obj.aliases.append(_get_text(node))
31
32 def property_handler(node, obj):
33 obj.properties.append(Property(node.getAttribute('type'), _get_text(node)))
34
35 def title_handler(node, obj):
36 obj.titles.append(Title(_get_text(node), node.getAttribute('xml:lang')))
37
38 def link_handler(node, obj):
39 l = Link()
40 l.rel = node.getAttribute('rel')
41 l.type = node.getAttribute('type')
42 l.href = node.getAttribute('href')
43 l.template = node.getAttribute('template')
44 obj.links.append(l)
45
46 handlers = {
47 'Expires': expires_handler,
48 'Subject': subject_handler,
49 'Alias': alias_handler,
50 'Property': property_handler,
51 'Link': link_handler,
52 'Title': title_handler,
53 }
54
55 def unknown_handler(node, obj):
56 obj.elements.append(Element(
57 name=node.tagName,
58 value=_get_text(node),
59 ))
60
61 def handle_node(node, obj):
62 handler = handlers.get(node.nodeName, unknown_handler)
63 if handler and node.nodeType == node.ELEMENT_NODE:
64 handler(node, obj)
65
66 doc = parseString(content)
67 root = doc.documentElement
68
69 rd = RD(root.getAttribute('xml:id'))
70
71 for name, value in list(root.attributes.items()):
72 if name != 'xml:id':
73 rd.attributes.append((name, value))
74
75 for node in root.childNodes:
76 handle_node(node, rd)
77 if node.nodeName == 'Link':
78 link = rd.links[-1]
79 for child in node.childNodes:
80 handle_node(child, link)
81
82 return rd
83
84
85 def dumps(xrd):
86
87 doc = getDOMImplementation().createDocument(XRD_NAMESPACE, "XRD", None)
88 root = doc.documentElement
89 root.setAttribute('xmlns', XRD_NAMESPACE)
90
91 if xrd.xml_id:
92 root.setAttribute('xml:id', xrd.xml_id)
93
94 for attr in xrd.attributes:
95 root.setAttribute(attr.name, attr.value)
96
97 if xrd.expires:
98 node = doc.createElement('Expires')
99 node.appendChild(doc.createTextNode(xrd.expires.isoformat()))
100 root.appendChild(node)
101
102 if xrd.subject:
103 node = doc.createElement('Subject')
104 node.appendChild(doc.createTextNode(xrd.subject))
105 root.appendChild(node)
106
107 for alias in xrd.aliases:
108 node = doc.createElement('Alias')
109 node.appendChild(doc.createTextNode(alias))
110 root.appendChild(node)
111
112 for prop in xrd.properties:
113 node = doc.createElement('Property')
114 node.setAttribute('type', prop.type)
115 if prop.value:
116 node.appendChild(doc.createTextNode(str(prop.value)))
117 else:
118 node.setAttribute('xsi:nil', 'true')
119 root.appendChild(node)
120
121 for element in xrd.elements:
122 node = doc.createElement(element.name)
123 node.appendChild(doc.createTextNode(element.value))
124 root.appendChild(node)
125
126 for link in xrd.links:
127
128 if link.href and link.template:
129 raise ValueError('only one of href or template attributes may be specified')
130
131 link_node = doc.createElement('Link')
132
133 if link.rel:
134 link_node.setAttribute('rel', link.rel)
135
136 if link.type:
137 link_node.setAttribute('type', link.type)
138
139 if link.href:
140 link_node.setAttribute('href', link.href)
141
142 if link.template:
143 link_node.setAttribute('template', link.template)
144
145 for title in link.titles:
146 node = doc.createElement('Title')
147 node.appendChild(doc.createTextNode(str(title)))
148 if title.lang:
149 node.setAttribute('xml:lang', title.lang)
150 link_node.appendChild(node)
151
152 for prop in link.properties:
153 node = doc.createElement('Property')
154 node.setAttribute('type', prop.type)
155 if prop.value:
156 node.appendChild(doc.createTextNode(str(prop.value)))
157 else:
158 node.setAttribute('xsi:nil', 'true')
159 link_node.appendChild(node)
160
161 root.appendChild(link_node)
162
163 return doc