class ElementElement(XsltElement):
    category = CategoryTypes.INSTRUCTION
    content = ContentInfo.Template
    legalAttrs = {
        'name': AttributeInfo.RawQNameAvt(required=1),
        'namespace': AttributeInfo.UriReferenceAvt(isNsName=1),
        'use-attribute-sets': AttributeInfo.QNames(),
    }

    def instantiate(self, context, processor):
        context.processorNss = self.namespaces
        context.currentInstruction = self

        (prefix, local) = self._name.evaluate(context)
        if prefix is not None:
            name = prefix + u':' + local
        else:
            name = local

        # From sec. 7.1.2 of the XSLT spec,
        #  1. if 'namespace' attr is not present, use ns in scope, based on prefix
        #    from the element QName in the 'name' attr value; if no prefix, use
        #    default ns in scope
        #  2. if 'namespace' attr is present and empty string, use empty ns ALWAYS
        #  3. if 'namespace' attr is present, namespace is attr value
        #
        if not self._namespace:
            if prefix is not None:
                if not self.namespaces.has_key(prefix):
                    raise XsltRuntimeException(Error.UNDEFINED_PREFIX, self,
                                               prefix)
                namespace = self.namespaces[prefix]
            else:
                namespace = self.namespaces[None]

        else:
            namespace = (self._namespace and self._namespace.evaluate(context)
                         or EMPTY_NAMESPACE)

        self.execute(context, processor, name, namespace)
        return

    def execute(self, context, processor, name, namespace):
        #FIXME: Use proper pysax AttributeList objects
        processor.writers[-1].startElement(name, namespace)
        for attr_set_name in self._use_attribute_sets:
            try:
                attr_set = processor.attributeSets[attr_set_name]
            except KeyError:
                raise XsltRuntimeException(Error.UNDEFINED_ATTRIBUTE_SET, self,
                                           attr_set_name)
            attr_set.instantiate(context, processor)

        for child in self.children:
            child.instantiate(context, processor)

        processor.writers[-1].endElement(name, namespace)
        return
Beispiel #2
0
class OutputElement(XsltElement):
    category = CategoryTypes.TOP_LEVEL_ELEMENT
    content = ContentInfo.Empty
    legalAttrs = {
        'method' : AttributeInfo.QName(),
        'version' : AttributeInfo.NMToken(),
        'encoding' : AttributeInfo.String(),
        'omit-xml-declaration' : AttributeInfo.YesNo(),
        'standalone' : AttributeInfo.YesNo(),
        'doctype-public' : AttributeInfo.String(),
        'doctype-system' : AttributeInfo.String(),
        'cdata-section-elements' : AttributeInfo.QNames(),
        'indent' : AttributeInfo.YesNo(),
        'media-type' : AttributeInfo.String(),
        'f:utfbom' : AttributeInfo.YesNo(
            default='no',
            description='Whether to force output of a byte order mark (BOM).  Usually used to generate a UTF-8 BOM.  Do not use unless you\'re sure you know what you\'re doing'),
        }
class AttributeSetElement(XsltElement):

    category = CategoryTypes.TOP_LEVEL_ELEMENT
    content = ContentInfo.Rep(ContentInfo.QName(XSL_NAMESPACE,
                                                'xsl:attribute'))
    legalAttrs = {
        'name': AttributeInfo.QName(required=1),
        'use-attribute-sets': AttributeInfo.QNames(),
    }

    doesPrime = 1

    def prime(self, processor, context):
        processor.attributeSets[self._name] = self
        return

    def instantiate(self, context, processor, used=None):
        if used is None:
            used = []

        if self in used:
            raise XsltRuntimeException(Error.CIRCULAR_ATTRIBUTE_SET, self,
                                       self._name)
        else:
            used.append(self)

        old_vars = context.varBindings
        context.varBindings = processor.stylesheet.getGlobalVariables()

        for attr_set_name in self._use_attribute_sets:
            try:
                attr_set = processor.attributeSets[attr_set_name]
            except KeyError:
                raise XsltRuntimeException(Error.UNDEFINED_ATTRIBUTE_SET, self,
                                           attr_set_name)
            attr_set.instantiate(context, processor, used)

        for child in self.children:
            child.instantiate(context, processor)

        context.varBindings = old_vars
        used.remove(self)

        return
Beispiel #4
0
class UriToElementElement(ElementElement.ElementElement):
    """
    Extends xsl:element by deriving the constructed element's QName and
    namespace from the supplied URI reference. The URI reference is
    first resolved to absolute form. Then, if the resulting URI begins
    with an in-scope namespace, that namespace will be used as if it had
    been supplied as the 'namespace' attribute to xsl:element, and the
    remainder of the URI will be combined with a prefix from the
    in-scope namespace bindings and used as if supplied as the 'name'
    attribute to xsl:element.

    Otherwise, the supplied default-name and default-namespace will be
    used, effecting the same result as calling xsl:element with these
    values.

    The intent is to allow an RDF resource, as identified by a URI with
    a fragment component, to be easily converted into an element.
    """
    content = ContentInfo.Template
    legalAttrs = {
        'uri':
        AttributeInfo.UriReferenceAvt(
            description=
            'A URI to be used to create the element.  An attempt will be made to split the URI into a head and a tail such that the head matches an in-scope namespace URI.  If matched a qname will be constructed from the prefix of that namespace declaration and the tail of the URI and the namespace from the declaration will be used to complete an output element.',
            required=1),
        'default-name':
        AttributeInfo.RawQNameAvt(
            description=
            'Used if the given URI cannot be broken down using in-scope namespaces',
            required=1),
        'default-namespace':
        AttributeInfo.UriReferenceAvt(
            description=
            'Used if the given URI cannot be broken down using in-scope namespaces',
            isNsName=1),
        'use-attribute-sets':
        AttributeInfo.QNames(),
    }

    def instantiate(self, context, processor):
        context.currentInstruction = self

        matched = 0
        uri = self._uri.evaluate(context)
        for (prefix, namespace) in self.namespaces.items():
            if namespace and uri.startswith(namespace):
                local = uri.split(namespace)[1]
                if prefix:
                    qname = prefix + u':' + local
                else:
                    qname = local
                matched = 1
                break

        if matched:
            ElementElement.ElementElement.execute(self, context, processor,
                                                  qname, namespace)
            return
        else:
            self._name = self._default_name
            self._namespace = self._default_namespace
            return ElementElement.ElementElement.instantiate(
                self, context, processor)
Beispiel #5
0
class CopyElement(XsltElement):

    category = CategoryTypes.INSTRUCTION
    content = ContentInfo.Template
    legalAttrs = {
        'use-attribute-sets': AttributeInfo.QNames(),
    }

    def instantiate(self, context, processor):
        context.processorNss = self.namespaces

        node = context.node
        if node.nodeType == Node.TEXT_NODE:
            processor.writers[-1].text(node.data)

        elif node.nodeType == Node.ELEMENT_NODE:
            #FIXME: Use proper pysax AttributeList objects
            extraNss = {}
            for (namespace, local), attr in node.attributes.items():
                # Namespace nodes are automatically copied as well
                # See XSLT 1.0 Sect 7.5
                if namespace == XMLNS_NAMESPACE:
                    extraNss[local] = attr.value
            processor.writers[-1].startElement(node.nodeName,
                                               node.namespaceURI, extraNss)
            for attr_set_name in self._use_attribute_sets:
                try:
                    attr_set = processor.attributeSets[attr_set_name]
                except KeyError:
                    raise XsltRuntimeException(Error.UNDEFINED_ATTRIBUTE_SET,
                                               self, attr_set_name)
                attr_set.instantiate(context, processor)
            for child in self.children:
                child.instantiate(context, processor)
            processor.writers[-1].endElement(node.nodeName, node.namespaceURI)

        elif node.nodeType == Node.DOCUMENT_NODE:
            for child in self.children:
                child.instantiate(context, processor)

        elif node.nodeType == Node.ATTRIBUTE_NODE:
            if node.namespaceURI != XMLNS_NAMESPACE:
                processor.writers[-1].attribute(node.nodeName, node.nodeValue,
                                                node.namespaceURI)

        elif node.nodeType == Node.PROCESSING_INSTRUCTION_NODE:
            processor.writers[-1].processingInstruction(node.target, node.data)

        elif node.nodeType == Node.COMMENT_NODE:
            processor.writers[-1].comment(node.data)

        elif node.nodeType == NAMESPACE_NODE:
            #Relies on XmlWriter rules, which is very close to spec:
            #http://www.w3.org/1999/11/REC-xslt-19991116-errata/#E25
            processor.writers[-1]._namespaces[-1][
                node.nodeName] = node.nodeValue

        else:
            raise Exception("Unknown Node Type %d" % node.nodeType)

        return