Esempio n. 1
0
 def prepare(self, element, value):
     if value is None:
         return self.default
     if not value:
         raise XsltException(Error.INVALID_NCNAME_ATTR, value)
     if ':' in value:
         raise XsltException(Error.INVALID_NCNAME_ATTR, value)
     return value
Esempio n. 2
0
 def prepare(self, element, value):
     if value is None:
         return self.default
     if not value:
         raise XsltException(Error.INVALID_PREFIX_ATTR, value)
     if ':' in value:
         raise XsltException(Error.INVALID_PREFIX_ATTR, value)
     if value == '#default':
         value = None
     return value
Esempio n. 3
0
 def prepare(self, element, value):
     if value is None:
         return self.default
     if self._isNsName and \
         value == XML_NAMESPACE or value == XMLNS_NAMESPACE:
         raise XsltException(Error.INVALID_NS_URIREF_ATTR, value)
     return value
Esempio n. 4
0
 def prepare(self, element, value):
     if value is None:
         return self.default
     try:
         return float(value or self.default)
     except:
         raise XsltException(Error.INVALID_NUMBER_ATTR, value)
Esempio n. 5
0
    def _finalize(self, method):
        try:
            writerClass = self._methods[method]
        except KeyError:
            if method[0] is None:
                # display only localName if in the null namespace
                method = method[1]
            raise XsltException(Error.UNKNOWN_OUTPUT_METHOD, str(method))
        else:
            self._outputParams.setDefault('method', method)

        if writerClass is XmlWriter.XmlWriter and \
               self._outputParams.cdataSectionElements:
            writerClass = XmlWriter.CdataSectionXmlWriter
        # Save our instance variables for use after reinitializing
        stream, stack = self._stream, self._stack
        del self._stream
        del self._stack
        self.__class__ = writerClass
        writerClass.__init__(self, self._outputParams, stream)

        # Do the saved callbacks
        self.startDocument()
        newline = 0
        for cmd, args, kw in stack:
            if newline:
                self.text(u'\n')
            else:
                newline = 1
            getattr(self, cmd)(*args, **kw)
        return
Esempio n. 6
0
 def parseAVT(self, avt):
     """DEPRECATED: specify an attribute in 'legalAttrs' instead."""
     if avt is None: return None
     try:
         return AttributeValueTemplate.AttributeValueTemplate(avt)
     except SyntaxError, error:
         raise XsltException(Error.INVALID_AVT, avt, self.baseUri,
                             self.lineNumber, self.columnNumber, str(error))
Esempio n. 7
0
 def prepare(self, element, value):
     if value is None:
         if self.default is None:
             return None
         value = self.default
     elif not IsQName(value):
         raise XsltException(Error.INVALID_QNAME_ATTR, value)
     return SplitQName(value)
Esempio n. 8
0
    def attribute(self, name, value, namespace=EMPTY_NAMESPACE):
        """
        add an attribute to an element

        name - the qualified name of the attribute
        value - the attribute value: must be Unicode
        namespace - must be Unicode or Ft.Xml.EMPTY_NAMESPACE (the default)

        Strives for "sanity".  For brilliant definition thereof, c.f. Joe English
        http://lists.xml.org/archives/xml-dev/200204/msg00170.html
        Uses terminology from that article
        See also discussions starting
        http://lists.fourthought.com/pipermail/4suite-dev/2003-March/001294.html
        http://lists.fourthought.com/pipermail/4suite-dev/2003-March/001283.html

        Note: attribute output is computed as invoked.
        This means that the ugly case

        attribute(u"foo", u"bar", "http://some-ns/")
        attribute(u"x:foo", u"baz", "http://some-ns/")

        will result in the ugly
          xmlns:org.4suite.4xslt.ns0="http://some-ns/"
          org.4suite.4xslt.ns0:foo="baz"

        The user can easily correct this by reversing the
        order of the calls
        """
        if not self._elementName:
            if self._inFirstElement:
                raise XsltException(Error.ATTRIBUTE_ADDED_TOO_LATE)
            else:
                raise XsltException(Error.ATTRIBUTE_ADDED_TO_NON_ELEMENT)
        (prefix, local) = SplitQName(name)
        if namespace != EMPTY_NAMESPACE:
            new_name = self._updateNamespace(prefix,
                                             namespace,
                                             local,
                                             forcePrefix=1)
            if new_name: name = new_name
        else:
            name = local

        self._attributes[name] = value
        return
Esempio n. 9
0
 def parsePattern(self, pattern):
     """DEPRECATED: specify an attribute in 'legalAttrs' instead."""
     if pattern is None: return None
     p = _xpattern_parser.new()
     try:
         return p.parse(pattern)
     except SyntaxError, error:
         raise XsltException(Error.INVALID_PATTERN, pattern, self.baseUri,
                             self.lineNumber, self.columnNumber, str(error))
Esempio n. 10
0
    def prepare(self, element, value):
        if value is None:
            if self.default is None:
                return None
            value = self.default
        elif not value:
            raise XsltException(Error.QNAME_BUT_NOT_NCNAME, value)

        try:
            index = value.index(':')
        except ValueError:
            raise XsltException(Error.QNAME_BUT_NOT_NCNAME, value)
        prefix, local = value[:index], value[index+1:]
        try:
            namespace = element.namespaces[prefix]
        except KeyError:
            raise XsltRuntimeException(Error.UNDEFINED_PREFIX,
                                       element, prefix)
        return (namespace, local)
Esempio n. 11
0
 def parseExpression(self, expression):
     """DEPRECATED: specify an attribute in 'legalAttrs' instead."""
     if expression is None: return None
     p = _xpath_parser.new()
     try:
         return p.parse(expression)
     except SyntaxError, error:
         raise XsltException(Error.INVALID_EXPRESSION, expression,
                             self.baseUri, self.lineNumber,
                             self.columnNumber, str(error))
    def __init__(self, source, validator=None, element=None):
        self.source = source
        self.validator = validator
        self.element = element

        try:
            # parts is a list of unicode and/or parsed XPath
            parts = _AvtParser.parse(source)
        except SyntaxError, exc:
            raise XsltException(Error.AVT_SYNTAX)
Esempio n. 13
0
 def prepare(self, element, value):
     if value is None:
         if self.default is None:
             return None
         value = self.default
     try:
         expression = _xpath_parser.parse(value)
     except SyntaxError, error:
         raise XsltException(Error.INVALID_EXPRESSION, value,
                             element.baseUri, element.lineNumber,
                             element.columnNumber, str(error))
Esempio n. 14
0
 def prepare(self, element, value):
     if value is None:
         return _ConstantValue(self.reprocess(element, self.default))
     elif '{' not in value and '}' not in value:
         return _ConstantValue(self.reprocess(element, value))
     try:
         return AttributeValueTemplate(value, self, element)
     except SyntaxError, error:
         # an error from the XPath parser
         raise XsltException(Error.INVALID_AVT, value,
                             element.baseUri, element.lineNumber,
                             element.columnNumber, str(error))
Esempio n. 15
0
 def prepare(self, element, value):
     if value is None:
         if self.default:
             value = self.default
         else:
             return None
     try:
         return _xpattern_parser.parse(value)
     except SyntaxError, error:
         raise XsltException(Error.INVALID_PATTERN, value,
                             element.baseUri, element.lineNumber,
                             element.columnNumber, str(error))
Esempio n. 16
0
 def prepare(self, element, value):
     if value is None:
         return self.default
     if value not in self.values:
         # check for a AttributeInfo instance
         allowed = filter(lambda v, t=type(self): type(v) is t, self.values)
         for info in allowed:
             try:
                 allowed.prepare(element, value)
                 return value
             except:
                 pass
         # if we get here it is an error
         raise XsltException(Error.INVALID_ATTR_CHOICE, value, str(self))
     return value
Esempio n. 17
0
    def prepare(self, element, value):
        if value is None:
            if self.default is None:
                return None
            value = self.default
        elif not IsQName(value):
            raise XsltException(Error.INVALID_QNAME_ATTR, value)

        prefix, local = SplitQName(value)
        if prefix:
            try:
                namespace = element.namespaces[prefix]
            except KeyError:
                raise XsltRuntimeException(Error.UNDEFINED_PREFIX,
                                           element, prefix)
        else:
            namespace = EMPTY_NAMESPACE
        return (namespace, local)
Esempio n. 18
0
class XsltElement(XsltNode):

    category = CategoryTypes.RESULT_ELEMENT
    content = ContentInfo.Template
    validator = ContentInfo.Validator(content)
    legalAttrs = None  # this means no error checking or defaulting

    def __init__(self, root, namespaceUri, localName, baseUri):
        self.root = root
        self.baseUri = baseUri
        self.expandedName = (namespaceUri, localName)
        self.children = []
        self.attributes = {}
        self.namespaces = {}
        return

    def insertChild(self, index, child):
        """INTERNAL USE ONLY"""
        self.children.insert(index, child)
        child.parent = self
        if child.doesSetup:
            child.setup()
        return

    def appendChild(self, child):
        """INTERNAL USE ONLY"""
        self.children.append(child)
        child.parent = self
        if child.doesSetup:
            child.setup()
        return

    def parseAVT(self, avt):
        """DEPRECATED: specify an attribute in 'legalAttrs' instead."""
        if avt is None: return None
        try:
            return AttributeValueTemplate.AttributeValueTemplate(avt)
        except SyntaxError, error:
            raise XsltException(Error.INVALID_AVT, avt, self.baseUri,
                                self.lineNumber, self.columnNumber, str(error))
        except XsltException, error:
            raise XsltException(Error.INVALID_AVT, avt, self.baseUri,
                                self.lineNumber, self.columnNumber,
                                error.args[0])
Esempio n. 19
0
    def _setupNamespaceAliases(self, aliases):
        merged = {}
        for alias in aliases:
            stylesheet_ns = alias.namespaces[alias._stylesheet_prefix]
            if stylesheet_ns in merged:
                existing = merged[stylesheet_ns].importIndex
                if existing < alias.importIndex:
                    merged[stylesheet_ns] = alias
                elif existing == alias.importIndex:
                    raise XsltException(Error.DUPLICATE_NAMESPACE_ALIAS,
                                        alias._stylesheet_prefix)
            else:
                merged[stylesheet_ns] = alias

        for stylesheet_ns, alias in merged.items():
            namespace = alias.namespaces[alias._result_prefix]
            prefix = alias._result_prefix
            self.namespaceAliases[stylesheet_ns] = (namespace, prefix)
        return
Esempio n. 20
0
    def __init__(self, format):
        self._format = format
        groups = _token_re.findall(format)
        if not groups:
            raise XsltException(Error.ILLEGAL_NUMBER_FORMAT_VALUE,
                                self._format)

        self.prefix = groups[0][0]
        self.suffix = groups[-1][2]

        toks = self.tokens = []
        seps = self.separators = []
        for group in groups[:-1]:
            toks.append(group[1])
            seps.append(group[2])
        toks.append(groups[-1][1])
        if not seps:
            seps.append('.')
        return
Esempio n. 21
0
    def setup(self):
        # Check for deprecated f:node-set
        if (FT_EXT_NAMESPACE, 'node-set') in self.attributes:
            warnings.warn(
                "You are using the deprecated f:node-set attribute"
                " on xsl:variable or xsl:param.  Please switch to"
                " using exslt:node-set", DeprecationWarning, 2)

        # check for a bad binding
        if self._select and self.children:
            raise XsltException(Error.VAR_WITH_CONTENT_AND_SELECT, self._name)

        # See the bottom of this file for these helper "nodes"
        binding_save = self.parent.children[0]
        if not isinstance(binding_save, PushVariablesNode):
            # varBindings not yet saved for this level in the stylesheet tree
            parent = self.parent
            binding_save = PushVariablesNode(parent.root, parent.baseUri)
            parent.insertChild(0, binding_save)
            parent.root.primeInstructions.append(binding_save)
        return
Esempio n. 22
0
    def _parseSrc(self, isrc, features, properties):
        self._input_source = isrc

        parser = Sax.CreateParser()
        parser.setContentHandler(self)
        for featurename, value in features:
            parser.setFeature(featurename, value)

        # Always set whitespace rules property
        parser.setProperty(Sax.PROPERTY_WHITESPACE_RULES,
                           STYLESHEET_WHITESPACE_RULES)
        for propertyname, value in properties:
            parser.setProperty(propertyname, value)

        try:
            parser.parse(isrc)
        except SAXParseException, e:
            e = e.getException() or e
            if isinstance(e, XsltException):
                raise e
            raise XsltException(Error.STYLESHEET_PARSE_ERROR, isrc.uri, e)
Esempio n. 23
0
    def _computeGlobalVar(self, vname, context, processed, deferred,
                          overriddenParams, processor):
        vnode = self._topVariables[0][vname]

        if vnode in deferred:
            raise XsltException(Error.CIRCULAR_VAR, vname[0], vname[1])
        if vnode in processed:
            return
        # Is it an <xsl:param>?
        # expandedName is a tuple (namespace-uri, local-name)
        if vnode.expandedName[1][0] == 'p':
            if vname in overriddenParams:
                context.varBindings[vname] = overriddenParams[vname]
            else:
                finished = 0
                while not finished:
                    orig_depth = len(processor.writers)
                    try:
                        vnode.instantiate(context, processor)
                        finished = 1
                    except XPath.RuntimeException, e:
                        if e.errorCode == XPath.RuntimeException.UNDEFINED_VARIABLE:
                            #Remove any aborted and possibly unbalanced
                            #outut handlers on the stack
                            depth = len(processor.writers)
                            for i in xrange(depth - orig_depth):
                                processor.writers.pop()
                            #Defer the current and try evaluating the
                            #one that turned up undefined
                            deferred.append(vnode)
                            self._computeGlobalVar((e.params[0], e.params[1]),
                                                   context, processed, deferred,
                                                   overriddenParams,
                                                   processor)
                            deferred.remove(vnode)
                        else:
                            raise
                #Set up so that later stylesheets will get overridden by
                #parameter values set in higher-priority stylesheets
                overriddenParams[vname] = context.varBindings[vname]
Esempio n. 24
0
    def _setupDecimalFormats(self, decimal_formats):
        for df in decimal_formats:
            name, format = df.getFormatInfo()
            existing = self.decimalFormats.get(name)
            if existing and existing != format:
                # conflicting formats
                if name:
                    # name is (namespace-uri, local-name)
                    if name[0]:
                        name = df.namespaces[name[0]] + ':' + name[1]
                    else:
                        name = name[1]
                else:
                    name = '#default'
                raise XsltException(Error.DUPLICATE_DECIMAL_FORMAT, name)
            self.decimalFormats[name] = format

        if None not in self.decimalFormats:
            # no default format specified
            self.decimalFormats[None] = ('.', ',', 'Infinity', '-', 'NaN', '%',
                                         unichr(0x2030), '0', '#', ';')
        return
Esempio n. 25
0
    def format(self, numbers, groupSize, groupSeparator):
        result = []
        zipped = map(None, numbers, self.tokens, self.separators)
        last_separator = self.prefix
        for number, token, separator in zipped[:len(numbers)]:
            if number < 0: number = 0
            result.append(last_separator)
            token = token or self.tokens[-1]
            last_separator = separator or self.separators[-1]
            if token[-1] == '1':
                result.append(
                    self._numeric(number, len(token), groupSize,
                                  groupSeparator))
            elif re.match('[A-HJ-Za-hj-z]$', token):
                result.append(self._alpha(number, token[0]))
            elif token in ('I', 'i'):
                result.append(self._roman(number, token.islower()))
            else:
                raise XsltException(Error.ILLEGAL_NUMBER_FORMAT_VALUE,
                                    self._format)

        result.append(self.suffix)
        return u''.join(result)
Esempio n. 26
0
 def setup(self):
     if not self.children:
         raise XsltException(Error.CHOOSE_REQUIRES_WHEN)
     return
Esempio n. 27
0
    def _setupTemplates(self, templates):
        named_tpls = self.namedTemplates
        match_tpls = self.matchTemplates

        shortcuts = []
        for template, position in zip(templates, xrange(len(templates))):
            # A 'shortcut' is (sort_key, template_info)
            (shorts, name) = template.getTemplateInfo(position)
            if name:
                # for call-templates
                existing = named_tpls.get(name)
                if existing:
                    if existing.importIndex == template.importIndex:
                        raise XsltException(Error.DUPLICATE_NAMED_TEMPLATE, name)
                    elif existing.importIndex > template.importIndex:
                        pass
                    else:
                        # The new template has a higher import precedence
                        # so replace what was already there.
                        named_tpls[name] = template
                else:
                    # The first occurrence of a template with this name.
                    named_tpls[name] = template

            shortcuts.extend(shorts)

        # Sort using the sort key, where it is:
        #   (<import precedence>, <template priority>, <stylesheet position>)
        shortcuts.sort()
        # We want the highest numbers first
        shortcuts.reverse()

        # Make the lookup tables. A lookup table is first keyed by mode,
        # then keyed by node type, then, if an element, keyed by expanded name
        for sort_key, template_info in shortcuts:
            mode, pattern_info, (node_type, expanded_name) = template_info

            # Save the sort key for use in matching
            pattern_info = (sort_key, pattern_info)

            mode_table = match_tpls.get(mode)
            if not mode_table:
                mode_table = match_tpls[mode] = {}

            type_table = mode_table.get(node_type)
            if not type_table:
                if node_type == Node.ELEMENT_NODE:
                    # Elements are further keyed by expanded name
                    type_list = [pattern_info]
                    mode_table[node_type] = {expanded_name : type_list}
                else:
                    mode_table[node_type] = [pattern_info]
            elif node_type == Node.ELEMENT_NODE:
                # Elements are further keyed by expanded name
                type_list = type_table.get(expanded_name)
                if not type_list:
                    type_table[expanded_name] = [pattern_info]
                else:
                    type_list.append(pattern_info)
            else:
                # Every other node type gets lumped into a single list
                # for that node type
                type_table.append(pattern_info)

        #self._printMatchTemplates()
        return
Esempio n. 28
0
 def prepare(self, element, value):
     if value is None:
         return self.default and self.default == 'yes'
     elif value not in ['yes', 'no']:
         raise XsltException(Error.INVALID_ATTR_CHOICE, value, str(self))
     return value == 'yes'
Esempio n. 29
0
    def applyTemplates(self, context, processor, params=None, maxImport=None):
        # Set the current node for this template application
        save_current = context.currentNode
        node = context.currentNode = context.node
        context.stylesheet = self
        #print
        #print "#" * 60
        #print "finding template for node", repr(context.node)

        mode_table = self.matchTemplates.get(context.mode)
        if not mode_table:
            # No patterns defined in this mode
            return 0

        patterns = []
        node_type = node.nodeType
        if node_type == Node.ELEMENT_NODE:
            table = mode_table.get(node_type)
            if table:
                key = (node.namespaceURI, node.localName)
                # First use those template which could match this expanded name
                patterns.extend(table.get(key, []))
                # Then add those that are wildcard tests ('*' and 'prefix:*')
                patterns.extend(table.get(None, []))
        else:
            patterns.extend(mode_table.get(node_type, []))

        # For any node type add those patterns that don't have a distinct type:
        #   node(), id() and key() patterns
        patterns.extend(mode_table.get(None, []))

        # Early exit for no matches
        if not patterns:
            return 0

        # If this is called from apply-imports, remove those patterns
        # with a higher import precedence than what was specified.
        if maxImport is not None:
            patterns = filter(lambda x, m=maxImport: x[0][0] < m, patterns)

        # Since the patterns may come from different tables, resort them
        patterns.sort()
        patterns.reverse() # highest numbers first

        if 1: # recovery_method == Recovery.SILENT
            # (default until recovery behaviour is selectable)
            # Just use the first matching pattern since they are
            # already sorted in descending order.
            for sort_key, (pattern, axis_type, template) in patterns:
                context.processorNss = template.namespaces
                if pattern.match(context, context.node, axis_type):
                    # let Python collect this list to reduce memory usage
                    del patterns
                    # Make sure the template starts with a clean slate
                    current_variables = context.varBindings
                    context.varBindings = self.globalVars
                    try:
                        template.instantiate(context, processor, params)
                    finally:
                        context.currentNode = save_current
                        context.varBindings = current_variables
                    return 1
        else: # recovery_method in (Recovery.WARNING, Recovery.NONE)
            # Find all templates that match the context node

            # Use the import index, priority and position from the last
            # possible matching pattern as starting points.
            highest_import, highest_priority, last_position = patterns[-1][0]
            matches = []
            for sort_key, (pattern, axis_type, template) in patterns:
                import_index, priority, position = sort_key

                if import_index < highest_import or \
                   (import_index == highest_import
                    and priority < highest_priority):
                    # Passed the point of possible conflicts, we can stop
                    break

                context.processorNss = template.namespaces
                if pattern.match(context, context.node, axis_type):
                    matches.append((template, pattern))

            if len(matches) > 1:
                # Report the template conflicts
                locations = []
                for template, pattern in matches:
                    locations.append((template.baseUri, template.lineNumber,
                                      template.columnNumber, repr(pattern)))

                # Sort them based on position
                locations.sort()

                locations = [
                        MessageSource.TEMPLATE_CONFLICT_LOCATION % location
                        for location in locations
                        ]
                exception = XsltException(Error.MULTIPLE_MATCH_TEMPLATES,
                                          context.node, '\n'.join(locations))

                if 1: # recovery_method == Recovery.WARNING
                    processor.warning(str(exception))
                else:
                    raise exception

            if matches:
                template = matches[0][0]
                # let Python collect these list to reduce memory usage
                del patterns
                del matches

                # Since the patterns were sorted to start with, use the first
                context.processorNss = template.namespaces
                template.instantiate(context, processor, params)
                context.currentNode = save_current
                return 1

        # Nothing matched
        return 0
Esempio n. 30
0
 def prepare(self, element, value):
     if value is None:
         return self.default
     if len(value) > 1:
         raise XsltException(Error.INVALID_CHAR_ATTR, value)
     return value