Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
class AttributeElement(XsltElement):
    category = CategoryTypes.INSTRUCTION
    content = ContentInfo.Template
    legalAttrs = {
        'name': AttributeInfo.RawQNameAvt(required=1),
        'namespace': AttributeInfo.UriReferenceAvt(isNsName=1),
    }

    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 + ':' + local
        else:
            name = local
        if name == 'xmlns':
            raise XsltRuntimeException(Error.BAD_ATTRIBUTE_NAME, self, name)

        # From sec. 7.1.3 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
        #    empty namespace
        #  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 = EMPTY_NAMESPACE
        else:
            namespace = (self._namespace and self._namespace.evaluate(context)
                         or EMPTY_NAMESPACE)

        processor.pushResultString()
        had_nontext = 0
        try:
            for child in self.children:
                child.instantiate(context, processor)
                if processor.writers[-1].had_nontext:
                    had_nontext = 1
        finally:
            if had_nontext:
                raise XsltRuntimeException(Error.NONTEXT_IN_ATTRIBUTE, self)
            content = processor.popResult()

        processor.writers[-1].attribute(name, content, namespace)
        return
Ejemplo n.º 3
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)