Viewing file: XLinkElements.py (5.35 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
######################################################################## # $Header: /var/local/cvsroot/4Suite/Ft/Xml/XLink/XLinkElements.py,v 1.8 2005/02/25 11:23:45 mbrown Exp $ """ Classes representing XLink elements
Copyright 2005 Fourthought, Inc. (USA). Detailed license and copyright information: http://4suite.org/COPYRIGHT Project home, documentation, distributions: http://4suite.org/ """
from xml.dom import Node
from Ft.Xml import Domlette from Ft.Xml.XLink import XLINK_NAMESPACE
def Create(node, baseUri): """ Given an XLink element node, returns an object (one of the classes defined in this module) that contains the node, its principal XLink attribute values, and a 'process' method that can be invoked in order to process (follow or otherwise act upon) the element.
Used by the Ft.Xml.XLink.Processor.Processor. """ elemType = node.getAttributeNS(XLINK_NAMESPACE, u'type') return TypeMap.get(elemType, Literal)(node, baseUri)
class Literal: """ Base class for an XLink element. """ type = None
def __init__(self, node, iSrc): self.resource = node self.input_source = iSrc
def process(self): return
class Simple(Literal): """ A 'simple'-type XLink element. """
type = "simple"
def __init__(self, node, iSrc): Literal.__init__(self, node, iSrc) self.href = node.getAttributeNS(XLINK_NAMESPACE, u'href') self.role = node.getAttributeNS(XLINK_NAMESPACE, u'role') self.arcrole = node.getAttributeNS(XLINK_NAMESPACE, u'arcrole') self.title = node.getAttributeNS(XLINK_NAMESPACE, u'title') self.show = node.getAttributeNS(XLINK_NAMESPACE, u'show') self.actuate = node.getAttributeNS(XLINK_NAMESPACE, u'actuate') self.attributes = filter(lambda x: x.namespaceURI != XLINK_NAMESPACE, node.attributes.values())
def process(self): """ Processes a simple XLink element according to the following guidelines:
If xlink:actuate='onLoad' and xlink:show='replace', then the remote resource's document element's content (not the document element itself) and the content of the XLink element (if any) will together replace the XLink element.
If xlink:actuate='onLoad' and xlink:show='embed', then the remote resource's document element will replace the XLink element.
Any other XLink attribute combinations are ignored.
These behaviors constitute a reasonable approximation of the resource loading suggestions in XLink 1.0 sec. 5.6.1. """ resource = self.resource if self.actuate == "onLoad": doc = resource.rootNode if self.show == 'replace': # 1. parse the remote resource # FIXME: support XPointer newSrc = self.input_source.resolve(self.href, pubid=None, hint='XLink') newDoc = Domlette.NonvalidatingReader.parse(newSrc) # 2. copy the XLink element's children and non-XLink attrs # into the parsed remote resource's document element # (but why bother with the attrs if we don't use them?) for node in self.attributes: newDoc.documentElement.setAttributeNS(node.namespaceURI, node.nodeName, node.value) for child in resource.childNodes[:]: nChild = doc.importNode(child, True) newDoc.documentElement.appendChild(nChild)
# 3. copy the parsed remote resource's document element's # children (its original ones plus those from step 2) # and insert them before the XLink element, then remove # the XLink element if resource.parentNode is not None: parent = resource.parentNode else: parent = doc for child in newDoc.documentElement.childNodes[:]: newDoc.documentElement.removeChild(child) child = doc.importNode(child, True) parent.insertBefore(child, resource) parent.removeChild(resource)
elif self.show == 'embed': # 1. parse the remote resource # FIXME: support XPointer newSrc = self.input_source.resolve(self.href, pubid=None, hint='XLink') newDoc = Domlette.NonvalidatingReader.parse(newSrc) # 2. replace the XLink element with the parsed remote resource's # document element child = doc.importNode(newDoc.documentElement, True) if resource.parentNode is not None: resource.parentNode.replaceChild(child, resource) else: doc.replaceChild(child, resource)
class Extended(Literal): type = "extended"
class Locator(Literal): type = "locator"
class Arc(Literal): type = "arc"
class Resource(Literal): type = "resource"
class Title(Literal): type = "title"
TypeMap = { 'simple' : Simple, 'extended' : Extended, 'locator' : Locator, 'arc' : Arc, 'resource' : Resource, 'title' : Title, }
|