]>
Commit | Line | Data |
---|---|---|
511b6ecb MF |
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 |