123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- from xml.dom.minidom import getDOMImplementation, parseString, Node
- from rd.core import RD, Element, Link, Property, Title
- XRD_NAMESPACE = "http://docs.oasis-open.org/ns/xri/xrd-1.0"
- def _get_text(root):
- text = ''
- for node in root.childNodes:
- if node.nodeType == Node.TEXT_NODE and node.nodeValue:
- text += node.nodeValue
- else:
- text += _get_text(node)
- return text.strip() or None
- def loads(content):
- import isodate
- def expires_handler(node, obj):
- obj.expires = isodate.parse_datetime(_get_text(node))
- def subject_handler(node, obj):
- obj.subject = _get_text(node)
- def alias_handler(node, obj):
- obj.aliases.append(_get_text(node))
- def property_handler(node, obj):
- obj.properties.append(Property(node.getAttribute('type'), _get_text(node)))
- def title_handler(node, obj):
- obj.titles.append(Title(_get_text(node), node.getAttribute('xml:lang')))
- def link_handler(node, obj):
- l = Link()
- l.rel = node.getAttribute('rel')
- l.type = node.getAttribute('type')
- l.href = node.getAttribute('href')
- l.template = node.getAttribute('template')
- obj.links.append(l)
- handlers = {
- 'Expires': expires_handler,
- 'Subject': subject_handler,
- 'Alias': alias_handler,
- 'Property': property_handler,
- 'Link': link_handler,
- 'Title': title_handler,
- }
- def unknown_handler(node, obj):
- obj.elements.append(Element(
- name=node.tagName,
- value=_get_text(node),
- ))
- def handle_node(node, obj):
- handler = handlers.get(node.nodeName, unknown_handler)
- if handler and node.nodeType == node.ELEMENT_NODE:
- handler(node, obj)
- doc = parseString(content)
- root = doc.documentElement
- rd = RD(root.getAttribute('xml:id'))
- for name, value in list(root.attributes.items()):
- if name != 'xml:id':
- rd.attributes.append((name, value))
- for node in root.childNodes:
- handle_node(node, rd)
- if node.nodeName == 'Link':
- link = rd.links[-1]
- for child in node.childNodes:
- handle_node(child, link)
- return rd
- def dumps(xrd):
- doc = getDOMImplementation().createDocument(XRD_NAMESPACE, "XRD", None)
- root = doc.documentElement
- root.setAttribute('xmlns', XRD_NAMESPACE)
- if xrd.xml_id:
- root.setAttribute('xml:id', xrd.xml_id)
- for attr in xrd.attributes:
- root.setAttribute(attr.name, attr.value)
- if xrd.expires:
- node = doc.createElement('Expires')
- node.appendChild(doc.createTextNode(xrd.expires.isoformat()))
- root.appendChild(node)
- if xrd.subject:
- node = doc.createElement('Subject')
- node.appendChild(doc.createTextNode(xrd.subject))
- root.appendChild(node)
- for alias in xrd.aliases:
- node = doc.createElement('Alias')
- node.appendChild(doc.createTextNode(alias))
- root.appendChild(node)
- for prop in xrd.properties:
- node = doc.createElement('Property')
- node.setAttribute('type', prop.type)
- if prop.value:
- node.appendChild(doc.createTextNode(str(prop.value)))
- else:
- node.setAttribute('xsi:nil', 'true')
- root.appendChild(node)
- for element in xrd.elements:
- node = doc.createElement(element.name)
- node.appendChild(doc.createTextNode(element.value))
- root.appendChild(node)
- for link in xrd.links:
- if link.href and link.template:
- raise ValueError('only one of href or template attributes may be specified')
- link_node = doc.createElement('Link')
- if link.rel:
- link_node.setAttribute('rel', link.rel)
- if link.type:
- link_node.setAttribute('type', link.type)
- if link.href:
- link_node.setAttribute('href', link.href)
- if link.template:
- link_node.setAttribute('template', link.template)
- for title in link.titles:
- node = doc.createElement('Title')
- node.appendChild(doc.createTextNode(str(title)))
- if title.lang:
- node.setAttribute('xml:lang', title.lang)
- link_node.appendChild(node)
- for prop in link.properties:
- node = doc.createElement('Property')
- node.setAttribute('type', prop.type)
- if prop.value:
- node.appendChild(doc.createTextNode(str(prop.value)))
- else:
- node.setAttribute('xsi:nil', 'true')
- link_node.appendChild(node)
- root.appendChild(link_node)
- return doc
|