def _initializeSheet(self, rootNode): if rootNode.namespaceURI == XSL_NAMESPACE: if rootNode.localName in ['stylesheet', 'transform']: if not rootNode.getAttributeNS(EMPTY_NAMESPACE, 'version'): raise XsltException(Error.STYLESHEET_MISSING_VERSION) #rootNode.__dict__['extensionNss'] = [] else: raise XsltException(Error.STYLESHEET_ILLEGAL_ROOT, rootNode.nodeName) else: vattr = rootNode.getAttributeNodeNS(XSL_NAMESPACE, 'version') if not vattr: root_nss = GetAllNs(rootNode) if filter(lambda x, n=root_nss: n[x] == XSL_NAMESPACE, root_nss.keys()): raise XsltException(Error.STYLESHEET_MISSING_VERSION) else: raise XsltException(Error.STYLESHEET_MISSING_VERSION_NOTE1) sheet = StylesheetElement(self._ownerDoc, XSL_NAMESPACE, 'transform', vattr.prefix, self._ssheetUri) sheet.setAttributeNS(EMPTY_NAMESPACE, 'version', vattr.value) tpl = TemplateElement(self._ownerDoc, XSL_NAMESPACE, 'template', vattr.prefix, self._ssheetUri) tpl.setAttributeNS(EMPTY_NAMESPACE, 'match', '/') sheet.appendChild(tpl) sheet.__dict__['extensionNss'] = [] self._nodeStack[-1].appendChild(sheet) # Ensure the literal element is a child of the template # endElement appends to the end of the nodeStack self._nodeStack.append(tpl) self._firstElement = 0 return
def setup(self): self.__dict__['_nss'] = xml.dom.ext.GetAllNs(self) mode_attr = self.getAttributeNS(EMPTY_NAMESPACE, 'mode') if mode_attr == '': self.__dict__['_mode'] = None else: split_name = Util.ExpandQName(mode_attr, namespaces=self._nss) self.__dict__['_mode'] = split_name select = self.getAttributeNS(EMPTY_NAMESPACE, 'select') if select: parser = XPathParser.XPathParser() self.__dict__['_expr'] = parser.parseExpression(select) else: self.__dict__['_expr'] = None self.__dict__['_sortSpecs'] = [] self.__dict__['_params'] = [] for child in self.childNodes: #All children should be sort and with-param if child.namespaceURI == XSL_NAMESPACE: if child.localName == 'sort': self._sortSpecs.append(child) elif child.localName == 'with-param': self._params.append(child) else: raise XsltException(Error.ILLEGAL_APPLYTEMPLATE_CHILD) else: raise XsltException(Error.ILLEGAL_APPLYTEMPLATE_CHILD) return
def instantiate(self, context, processor, nodeList=None, specList=None): if nodeList is None: nodeList = [] if specList is None: specList = [] origState = context.copy() context.setNamespaces(self._nss) if self._data_type: data_type = self._data_type.evaluate(context) if data_type not in ['text', 'number']: raise XsltException(Error.ILLEGAL_SORT_DATA_TYPE_VALUE) else: data_type = 'text' if self._case_order: case_order = self._case_order.evaluate(context) if case_order not in ['upper-first', 'lower-first']: raise XsltException(Error.ILLEGAL_SORT_CASE_ORDER_VALUE) else: case_order = 'lower-first' if self._order: order = self._order.evaluate(context) if order not in ['ascending', 'descending']: raise XsltException(Error.ILLEGAL_SORT_ORDER_VALUE) else: order = 'ascending' keys = [] node_dict = {} pos = 1 size = len(nodeList) tempState = context.copyNodePosSize() for node in nodeList: context.setNodePosSize((node, pos, size)) result = self._expr.evaluate(context) key = Conversions.StringValue(result) if not key in keys: keys.append(key) if node_dict.has_key(key): node_dict[key].append(node) else: node_dict[key] = [node] pos = pos + 1 context.setNodePosSize(tempState) keys.sort(lambda x, y, o=order, d=data_type, c=case_order: Cmp( x, y, o, d, c)) sorted_list = [] for key in keys: sub_list = node_dict[key] if len(sub_list) > 1 and specList: sub_list = specList[0].instantiate(context, processor, sub_list, specList[1:])[1] sorted_list = sorted_list + sub_list context.set(origState) return (context, sorted_list)
def _parse(self): parser = XPathParser.XPathParser() curr_plain_part = '' curr_template_part = '' in_plain_part = 1 split_form = re.split(g_braceSplitPattern, self.source) skip_flag = 0 for i in range(len(split_form)): segment = split_form[i] if skip_flag: skip_flag = skip_flag - 1 continue if segment in ['{', '}']: #Here we are accounting for a possible blank segment in between try: next = split_form[i + 1] + split_form[i + 2] except IndexError: next = None if next == segment: if in_plain_part: curr_plain_part = curr_plain_part + segment else: curr_template_part = curr_template_part + segment skip_flag = 2 elif segment == '{': if in_plain_part: self._plainParts.append(curr_plain_part) in_plain_part = 0 curr_plain_part = '' else: raise XsltException(Error.AVT_SYNTAX) else: if not in_plain_part: parsed = parser.parseExpression(curr_template_part) self._parsedParts.append(parsed) in_plain_part = 1 curr_template_part = '' else: raise XsltException(Error.AVT_SYNTAX) else: if in_plain_part: curr_plain_part = curr_plain_part + segment else: curr_template_part = curr_template_part + segment if in_plain_part: self._plainParts.append(curr_plain_part) else: raise XsltException(Error.AVT_SYNTAX)
def setup(self): self.__dict__['_name'] = self.getAttributeNS(EMPTY_NAMESPACE, 'name') if not self._name: raise XsltException(Error.ATTRIBUTESET_REQUIRES_NAME) self.__dict__['_useAttributeSets'] = string.splitfields( self.getAttributeNS(EMPTY_NAMESPACE, 'use-attribute-sets')) self.__dict__['_varBindings'] = {} self.__dict__['_nss'] = xml.dom.ext.GetAllNs(self) #Check that all children are attribute instructions for child in self.childNodes: if (child.namespaceURI, child.localName) != (xml.xslt.XSL_NAMESPACE, 'attribute'): raise XsltException(Error.ILLEGAL_ATTRIBUTESET_CHILD) return
def instantiate(self, context, processor): origState = context.copy() context.setNamespaces(self._nss) name = self._name.evaluate(context) namespace = self._namespace.evaluate(context) (prefix, local) = xml.dom.ext.SplitQName(name) if not namespace and prefix: namespace = context.processorNss[prefix] #FIXME: Use proper pysax AttributeList objects processor.writers[-1].startElement(name, namespace) for attr_set_name in self._useAttributeSets: split_name = Util.ExpandQName(attr_set_name, namespaces=context.processorNss) try: attr_set = processor.attributeSets[split_name] except KeyError: raise XsltException(Error.UNDEFINED_ATTRIBUTE_SET, attr_set_name) attr_set.use(context, processor) for child in self.childNodes: context = child.instantiate(context, processor)[0] processor.writers[-1].endElement(name) context.set(origState) return (context, )
class StylesheetReader(_ReaderBase): def __init__(self, force8Bit=0): _ReaderBase.__init__(self) self.force8Bit = force8Bit self._ssheetUri = '' return def fromUri(self, uri, baseUri='', ownerDoc=None, stripElements=None): self._ssheetUri = urllib.basejoin(baseUri, uri) result = _ReaderBase.fromUri(self, uri, baseUri, ownerDoc, stripElements) return result def fromStream(self, stream, baseUri='', ownerDoc=None, stripElements=None): if not xslt.g_registered: xslt.Register() self.initParser() self.initState(ownerDoc, baseUri) p = self.parser try: success = self.parser.ParseFile(stream) except XsltException: raise except Exception, e: for s in self._nodeStack: self.releaseNode(s) if p.ErrorCode: raise FtException(XML_PARSE_ERROR, p.ErrorLineNumber, p.ErrorColumnNumber, expat.ErrorString(p.ErrorCode)) else: raise self._ssheetUri = '' self.killParser() if not success: self.releaseNode(self._rootNode) self.releaseNode(self._ownerDoc) raise XsltException(Error.STYLESHEET_PARSE_ERROR, baseUri, p.ErrorLineNumber, p.ErrorColumnNumber, expat.ErrorString(p.ErrorCode)) self._completeTextNode() root = self._rootNode or self._ownerDoc if root.nodeType == Node.DOCUMENT_NODE: sheet = root.documentElement try: sheet.setup() except: sheet.reclaim() self.releaseNode(root) raise else: sheet = None rt = sheet or root return rt
def runStream(self, stream, ignorePis=0, topLevelParams=None, writer=None, baseUri='', outputStream=None): try: src = self._docReader.fromStream( stream, stripElements=self._getWsStripElements() ) except Exception, e: raise XsltException(Error.SOURCE_PARSE_ERROR, '<input stream>', e)
def runUri(self, uri, ignorePis=0, topLevelParams=None, writer=None, outputStream=None): try: src = self._docReader.fromUri(uri, stripElements=self._getWsStripElements()) except Exception, e: import traceback traceback.print_exc() raise XsltException(Error.SOURCE_PARSE_ERROR, uri, e)
def attribute(self, name, value, namespace=EMPTY_NAMESPACE): if not self._currElement: raise XsltException(Error.ATTRIBUTE_ADDED_AFTER_ELEMENT) value = TranslateCdata(value, self._outputParams.encoding) self._currElement.attrs[name] = TranslateCdataAttr(value) (prefix, local) = xml.dom.ext.SplitQName(name) self._namespaces[-1][prefix] = namespace return
def setup(self): self.__dict__['_test'] = self.getAttributeNS(EMPTY_NAMESPACE, 'test') if not self._test: raise XsltException(Error.WHEN_MISSING_TEST) self.__dict__['_nss'] = xml.dom.ext.GetAllNs(self) parser = XPathParser.XPathParser() self.__dict__['_expr'] = parser.parseExpression(self._test) return
def GenerateId(context, nodeSet=None): if nodeSet is not None and type(nodeSet) != type([]): raise XsltException(Error.WRONG_ARGUMENT_TYPE) if not nodeSet: return 'id' + ` id(context.node) ` else: node = Util.SortDocOrder(nodeSet)[0] return 'id' + ` id(node) `
def setup(self): parser = XPathParser.XPathParser() self.__dict__['_select'] = self.getAttributeNS(EMPTY_NAMESPACE, 'select') if not self._select: raise XsltException(Error.COPYOF_MISSING_SELECT) self.__dict__['_expr'] = parser.parseExpression(self._select) self.__dict__['_nss'] = xml.dom.ext.GetAllNs(self) return
def setup(self): self.__dict__['_disable_output_escaping'] = self.getAttributeNS( EMPTY_NAMESPACE, 'disable-output-escaping') == 'yes' self.__dict__['_nss'] = xml.dom.ext.GetAllNs(self) for child in self.childNodes: if child.nodeType == Node.ELEMENT_NODE: raise XsltException(Error.ILLEGAL_TEXT_CHILD) self.normalize() return
def setup(self): name = self.getAttributeNS(EMPTY_NAMESPACE, 'name') if not name: raise XsltException(Error.ATTRIBUTE_MISSING_NAME) self._name = AttributeValueTemplate(name) namespace = self.getAttributeNS(EMPTY_NAMESPACE, 'namespace') self._namespace = AttributeValueTemplate(namespace) self._nss = xml.dom.ext.GetAllNs(self) return
def setup(self): self.__dict__['_select'] = self.getAttributeNS(EMPTY_NAMESPACE, 'select') if not self._select: raise XsltException(Error.VALUEOF_MISSING_SELECT) self.__dict__['_disable_output_escaping'] = self.getAttributeNS( EMPTY_NAMESPACE, 'disable-output-escaping') == 'yes' self.__dict__['_nss'] = xml.dom.ext.GetAllNs(self) parser = XPathParser.XPathParser() self.__dict__['_expr'] = parser.parseExpression(self._select) return
def execute(self, node, ignorePis=0, topLevelParams=None, writer=None, baseUri='', outputStream=None): """ Run the stylesheet processor against the given XML DOM node with the stylesheets that have been registered. Does not mutate the DOM If writer is None, use the XmlWriter, otherwise, use the supplied writer """ #FIXME: What about ws stripping? topLevelParams = topLevelParams or {} if len(self._stylesheets) == 0: raise XsltException(Error.NO_STYLESHEET) self._outputParams = self._stylesheets[0].outputParams if writer: self.writers = [writer] else: self.addHandler(self._outputParams, outputStream, 0) self._namedTemplates = {} tlp = topLevelParams.copy() for sty in self._stylesheets: sty.processImports(node, self, tlp) named = sty.getNamedTemplates() for name,template_info in named.items(): if not self._namedTemplates.has_key(name): self._namedTemplates[name] = template_info for sty in self._stylesheets: tlp = sty.prime(node, self, tlp) #Run the document through the style sheets self.writers[-1].startDocument() context = XsltContext.XsltContext(node, 1, 1, None, processor=self) try: self.applyTemplates(context, None) self.writers[-1].endDocument() Util.FreeDocumentIndex(node) result = self.writers[-1].getResult() finally: self._reset() context.release() return result
def setup(self): self.__dict__['_nss'] = xml.dom.ext.GetAllNs(self) self.__dict__['_match'] = self.getAttributeNS(EMPTY_NAMESPACE, 'match') mode_attr = self.getAttributeNS(EMPTY_NAMESPACE, 'mode') if not mode_attr: self.__dict__['_mode'] = None else: split_name = Util.ExpandQName(mode_attr, namespaces=self._nss) self.__dict__['_mode'] = split_name name_attr = self.getAttributeNS(EMPTY_NAMESPACE, 'name') split_name = Util.ExpandQName(name_attr, namespaces=self._nss) self.__dict__['_name'] = split_name self.__dict__['_params'] = [] self.__dict__['_elements'] = [] for child in self.childNodes: if child.namespaceURI == XSL_NAMESPACE: if child.localName == 'param': self.__dict__['_params'].append(child) elif child.localName in ['choose', 'if']: self.__dict__['_elements'].append((1, child)) else: self.__dict__['_elements'].append((0, child)) else: self.__dict__['_elements'].append((0, child)) #A list of tuples #(pattern,qmatch,priority) #either pattern or qmatch will be present but not both self.__dict__['_patternInfo'] = [] if self._match: priority = self.getAttributeNS(EMPTY_NAMESPACE, 'priority') or None if priority is not None: try: priority = float(priority) except: raise XsltException(Error.ILLEGAL_TEMPLATE_PRIORITY) parser = XPatternParser.XPatternParser() shortcuts = parser.parsePattern(self._match).getMatchShortcuts() for pattern, (shortcut, extra_arg) in shortcuts: if priority is None: tpl_priority = pattern.priority else: tpl_priority = priority self.__dict__['_patternInfo'].append( (shortcut, extra_arg, tpl_priority))
def instantiate(self, context, processor): origState = context.copy() context.setNamespaces(self._nss) processor.pushResult() for child in self.childNodes: context = child.instantiate(context, processor)[0] result = processor.popResult() msg = Conversions.StringValue(result) processor.releaseRtf(result) if self._terminate == 'yes': raise XsltException(Error.STYLESHEET_REQUESTED_TERMINATION, msg) else: processor.xslMessage(msg) context.set(origState) return (context,)
def instantiate(self, context, processor): origState = context.copy() context.setNamespaces(self._nss) 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 processor.writers[-1].startElement(node.nodeName, node.namespaceURI) for attr_set_name in self._useAttributeSets: split_name = Util.ExpandQName(attr_set_name, namespaces=context.processorNss) try: attr_set = processor.attributeSets[split_name] except KeyError: raise XsltException(Error.UNDEFINED_ATTRIBUTE_SET, attr_set_name) attr_set.use(context, processor) for child in self.childNodes: context = child.instantiate(context, processor)[0] processor.writers[-1].endElement(node.nodeName) elif node.nodeType == Node.DOCUMENT_NODE: for child in self.childNodes: context = child.instantiate(context, processor)[0] elif node.nodeType == Node.ATTRIBUTE_NODE: if node.namespaceURI == XMLNS_NAMESPACE: nodeName = 'xmlns' + (node.localName and ':' + node.localName) processor.writers[-1].attribute(nodeName, node.nodeValue, node.namespaceURI) else: 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) else: raise Exception("Unknown Node Type %d" % node.nodeType) context.set(origState) return (context,)
def use(self, context, processor, used=None): if used is None: used = [] origState = context.copy() context.varBindings = self._varBindings for attr_set_name in self._useAttributeSets: split_name = Util.ExpandQName(attr_set_name, namespaces=context.processorNss) try: attr_set = processor.attributeSets[split_name] except KeyError: raise XsltException(Error.UNDEFINED_ATTRIBUTE_SET, attr_set_name) attr_set.use(context, processor) for child in self.childNodes: context = child.instantiate(context, processor)[0] context.set(origState) return context
def instantiate(self, context, processor): origState = context.copy() context.setNamespaces(self._nss) if self._select: result = self._expr.evaluate(context) #Check the result type. Note: we should really normalize the data typing so that we can throw an error if the result is not a node-set if type(result) != type([]): raise XsltException(Error.INVALID_FOREACH_SELECT) else: result = context.node.childNodes size = len(result) if size > 1 and self._sortSpecs: result = self._sortSpecs[0].instantiate(context, processor, result, self._sortSpecs[1:])[1] for ctr in range(size): node = result[ctr] context.setNodePosSize((node,ctr+1,size)) context.currentNode = node for child in self.childNodes: child.instantiate(context, processor)[0] context.set(origState) return (context,)
def instantiate(self, context, processor): origState = context.copy() context.setNamespaces(self._nss) processor.writers[-1].startElement(self._aliasNodeName, self._aliasUri, self._outputNss) for (name, uri, avt) in self.__attrs: value = avt.evaluate(context) processor.writers[-1].attribute(name, value, uri) for attr_set_name in self._useAttributeSets: split_name = Util.ExpandQName(attr_set_name, namespaces=context.processorNss) try: attr_set = processor.attributeSets[split_name] except KeyError: raise XsltException(Error.UNDEFINED_ATTRIBUTE_SET, attr_set_name) attr_set.use(context, processor) for child in self.childNodes: context = child.instantiate(context, processor)[0] processor.writers[-1].endElement(self._aliasNodeName) context.set(origState) return (context, )
def setup(self): self._nss = {} self._level = None self._count = None self._from = None self._value = None self._format = None self._lang = None self._letter_value = None self._grouping_separator = None self._grouping_size = None self._value_expr = None self._sibling_expr = None self._count_prior_doc_order_expr = None self._count_pattern = None self._ancorself_expr = None path_parser = XPathParser.XPathParser() pattern_parser = XPatternParser.XPatternParser() self.__dict__['_level'] = self.getAttributeNS(EMPTY_NAMESPACE, 'level') or 'single' if self._level not in ['single', 'multiple', 'any']: raise XsltException(Error.ILLEGAL_NUMBER_LEVEL_VALUE) self.__dict__['_count'] = self.getAttributeNS(EMPTY_NAMESPACE, 'count') self.__dict__['_from'] = self.getAttributeNS(EMPTY_NAMESPACE, 'from') self.__dict__['_value'] = self.getAttributeNS(EMPTY_NAMESPACE, 'value') format = self.getAttributeNS(EMPTY_NAMESPACE, 'format') self.__dict__[ '_format'] = format and AttributeValueTemplate.AttributeValueTemplate( format) or None lang = self.getAttributeNS(EMPTY_NAMESPACE, 'lang') self.__dict__[ '_lang'] = lang and AttributeValueTemplate.AttributeValueTemplate( lang) or None letter_value = self.getAttributeNS(EMPTY_NAMESPACE, 'letter-value') self.__dict__[ '_letter_value'] = letter_value and AttributeValueTemplate.AttributeValueTemplate( letter_value) or None grouping_separator = self.getAttributeNS(EMPTY_NAMESPACE, 'grouping-separator') self.__dict__[ '_grouping_separator'] = grouping_separator and AttributeValueTemplate.AttributeValueTemplate( grouping_separator) or None grouping_size = self.getAttributeNS(EMPTY_NAMESPACE, 'grouping-size') self.__dict__[ '_grouping_size'] = grouping_size and AttributeValueTemplate.AttributeValueTemplate( grouping_size) or None self.__dict__['_nss'] = xml.dom.ext.GetAllNs(self) #Prep computations if not self._count: #FIXME: Handle other node types???? self._count = '*[name()=name(current())]' self._count_pattern = pattern_parser.parsePattern(self._count) ancestor_or_self = "ancestor-or-self::node()" if self._from: ancestor_or_self = ancestor_or_self + '[ancestor::%s]' % ( self._from) self._ancorself_expr = path_parser.parseExpression(ancestor_or_self) if self._value: self._value_expr = path_parser.parseExpression(self._value) self._sibling_expr = None self._count_prior_doc_order_expr = None else: self._sibling_expr = path_parser.parseExpression( 'preceding-sibling::node()') patterns = pattern_parser.parsePattern(self._count)._patterns count_prior_doc_order = '' if self._from: froms = pattern_parser.parsePattern(self._from)._patterns pred = "[" for fro in froms: pred = pred + 'ancestor::' + repr(fro) if fro != froms[-1]: pred = pred + '|' pred = pred + ']' for count in patterns: if self._from: count_prior_doc_order = count_prior_doc_order + 'ancestor-or-self::' + repr( count) + pred + '|preceding::' + repr(count) + pred else: count_prior_doc_order = count_prior_doc_order + 'ancestor-or-self::' + repr( count) + '|preceding::' + repr(count) if count != patterns[-1]: count_prior_doc_order = count_prior_doc_order + '|' self._count_prior_doc_order_expr = path_parser.parseExpression( count_prior_doc_order) return
def instantiate(self, context, processor, nodeList=None, specList=None): if nodeList is None: nodeList = [] if specList is None: specList = [] origState = context.copy() context.setNamespaces(self._nss) if self._format: format = self._format.evaluate(context) else: format = '1' if self._grouping_separator: grouping_separator = self._grouping_separator.evaluate(context) else: grouping_separator = ',' if self._grouping_size: grouping_size = self._grouping_size.evaluate(context) else: grouping_size = '3' if grouping_separator and grouping_size: try: grouping_size = string.atoi(grouping_size) except ValueError: raise XsltException(Error.ILLEGAL_NUMBER_GROUPING_SIZE_VALUE) else: grouping_separator = None grouping_size = None if self._letter_value: letter_value = self._letter_value.evaluate(context) if letter_value not in ['alphabetic', 'traditional']: raise XsltException(Error.ILLEGAL_NUMBER_LETTER_VALUE_VALUE) value = [] tempState = context.copyNodePosSize() if self._value: result = self._value_expr.evaluate(context) value = [Conversions.NumberValue(result)] elif self._level == 'single': ancorself_result = self._ancorself_expr.evaluate(context) ancorself_result.reverse() for node in ancorself_result: context.node = node if self._count_pattern.match(context, context.node): break sibling_result = self._sibling_expr.evaluate(context) value = 1 for node in sibling_result: context.node = node if self._count_pattern.match(context, context.node): value = value + 1 value = [value] elif self._level == 'multiple': ancorself_result = self._ancorself_expr.evaluate(context) ancorself_result.reverse() count_result = [] for node in ancorself_result: context.node = node if self._count_pattern.match(context, context.node): count_result.append(node) context.setNodePosSize(tempState) value = [] for node in count_result: context.node = node sibling_result = self._sibling_expr.evaluate(context) lvalue = 1 for node in sibling_result: context.node = node if self._count_pattern.match(context, context.node): lvalue = lvalue + 1 value.insert(0, lvalue) elif self._level == 'any': count_result = self._count_prior_doc_order_expr.evaluate(context) value = [len(count_result)] context.setNodePosSize(tempState) format_tokens = [] format_separators = [] re_groups = g_formatToken.findall(format) if not re_groups: raise XsltException(Error.ILLEGAL_NUMBER_FORMAT_VALUE) pre_string = re_groups[0][0] post_string = re_groups[-1][2] for group in re_groups: format_tokens.append(group[1]) format_separators.append(group[2]) format_separators = ['.'] + format_separators[:-1] result = pre_string curr_index = 0 lft = len(format_tokens) lfs = len(format_separators) for number in value: if curr_index: result = result + curr_sep if curr_index < lft: curr_ft = format_tokens[curr_index] curr_sep = format_separators[curr_index] curr_index = curr_index + 1 else: curr_ft = format_tokens[-1] curr_sep = format_separators[-1] numstr = str(number) if curr_ft[-1] == '1': subresult = Group('0' * (len(curr_ft) - len(numstr)) + numstr, grouping_size, grouping_separator) result = result + subresult elif curr_ft == 'A': digits = Base26(number) #FIXME: faster with reduce for dig in digits: result = result + chr(ord('A') + dig - 1) elif curr_ft == 'a': digits = Base26(number) for dig in digits: result = result + chr(ord('a') + dig - 1) elif curr_ft == 'I': result = result + Roman.IToRoman(number) elif curr_ft == 'i': result = result + string.lower(Roman.IToRoman(number)) else: raise XsltException(Error.ILLEGAL_NUMBER_FORMAT_VALUE) processor.writers[-1].text(result + post_string) context.set(origState) return (context, )
def startElement(self, name, attribs): self._completeTextNode() (name, qname, nsattribs) = self._handleStartElementNss(name, attribs) nsuri = name[0] local = name[1] prefix = SplitQName(qname)[0] mapping = g_mappings.get(nsuri, None) del_extu = [] if mapping: if not mapping.has_key(local): if self._firstElement: raise XsltException(Error.STYLESHEET_ILLEGAL_ROOT, name) else: raise XsltException(Error.XSLT_ILLEGAL_ELEMENT, local) xsl_class = mapping[local] if xsl_class == IncludeElement: #Can the included sheet have literal result element as root? inc = self.clone().fromUri(nsattribs[('', 'href')], baseUri=self._ssheetUri, ownerDoc=self._ownerDoc) sty = inc.firstChild included_nss = GetAllNs(sty) for child in sty.childNodes[:]: self._nodeStack[-1].appendChild(child) #migrate old nss from stylesheet directly to new child for prefix in included_nss.keys(): if prefix: child.setAttributeNS(XMLNS_NAMESPACE, 'xmlns:' + prefix, included_nss[prefix]) else: child.setAttributeNS(XMLNS_NAMESPACE, 'xmlns', included_nss[prefix]) self._nodeStack.append(None) pDomlette.ReleaseNode(inc) return else: xsl_instance = xsl_class(self._ownerDoc, baseUri=self._ssheetUri) for aqname in nsattribs.getQNames(): (ansuri, alocal) = nsattribs.getNameByQName(aqname) value = nsattribs.getValueByQName(aqname) if ansuri != XMLNS_NAMESPACE and xsl_class == StylesheetElement: self._handleExtUris(ansuri, alocal, value, '', del_extu, xsl_instance) elif not ansuri and alocal not in xsl_instance.__class__.legalAttrs: raise XsltException(Error.XSLT_ILLEGAL_ATTR, aqname, xsl_instance.nodeName) xsl_instance.setAttributeNS(ansuri, aqname, value) else: if nsuri in self._extUris and self._extElements: #Default XsltElement behavior effects fallback ext_class = self._extElements.get((nsuri, local), XsltElement) xsl_instance = ext_class(self._ownerDoc, nsuri, local, prefix, self._ssheetUri) else: xsl_instance = LiteralElement(self._ownerDoc, nsuri, local, prefix, self._ssheetUri) for aqname in nsattribs.getQNames(): (ansuri, alocal) = nsattribs.getNameByQName(aqname) value = nsattribs.getValueByQName(aqname) if ansuri != XMLNS_NAMESPACE: self._handleExtUris(ansuri, alocal, value, '', del_extu, xsl_instance) if hasattr(xsl_instance.__class__, 'legalAttrs'): if not ansuri and alocal not in xsl_instance.__class__.legalAttrs: raise XsltException(Error.XSLT_ILLEGAL_ATTR, alocal, xsl_instance.nodeName) xsl_instance.setAttributeNS(ansuri, aqname, value) self._extUriStack.append(del_extu) if (xsl_instance.namespaceURI, xsl_instance.localName) == ( XSL_NAMESPACE, 'text') or xsl_instance.getAttributeNS( XML_NAMESPACE, 'space') == 'preserve': self._preserveStateStack.append(1) elif xsl_instance.getAttributeNS(XML_NAMESPACE, 'space') == 'default': self._preserveStateStack.append(0) else: self._preserveStateStack.append(self._preserveStateStack[-1]) if self._firstElement: self._initializeSheet(xsl_instance) self._nodeStack.append(xsl_instance) return
def applyImports(self, context, mode, params=None): params = params or {} if not self.sheetWithCurrTemplate[-1]: raise XsltException(Error.APPLYIMPORTS_WITH_NULL_CURRENT_TEMPLATE) self.sheetWithCurrTemplate[-1].applyImports(context, mode, self) return
class Processor: def __init__(self, reader=None): self._stylesheets = [] self.writers = [] self._reset() self._dummyDoc = g_domModule.Document() #Can be overridden self._styReader = StylesheetReader.StylesheetReader() self._docReader = reader or g_readerClass() self._lastOutputParams = None if not xslt.g_registered: xslt.Register() return def _reset(self): self.attributeSets = {} for sty in self._stylesheets: sty.reset() self.sheetWithCurrTemplate = [None] #A stack of writers, to support result-tree fragments self.writers = [] #self.extensionParams = {} return def _getWsStripElements(self): space_rules = {} for a_sheet in self._stylesheets: space_rules.update(a_sheet.spaceRules) strip_elements = map(lambda x: (x[0][0], x[0][1], x[1] == 'strip'), space_rules.items()) strip_elements.append((XSL_NAMESPACE,'text',0)) return strip_elements def registerExtensionModules(self, moduleList): return xslt.RegisterExtensionModules(moduleList) def setStylesheetReader(self, readInst): self._styReader = readInst def setDocumentReader(self, readInst): self._docReader = readInst def appendStylesheetUri(self, styleSheetUri, baseUri=''): sty = self._styReader.fromUri(styleSheetUri, baseUri) self._stylesheets.append(sty) return appendStylesheetFile = appendStylesheetUri def appendStylesheetNode(self, styleSheetNode, baseUri=''): """Accepts a DOM node that must be a document containing the stylesheet""" sty = StylesheetReader.FromDocument(styleSheetNode, baseUri) self._stylesheets.append(sty) return def appendStylesheetString(self, text, baseUri=''): sty = self._styReader.fromString(text, baseUri) self._stylesheets.append(sty) return def appendStylesheetStream(self, stream, baseUri=''): sty = self._styReader.fromStream(stream, baseUri) self._stylesheets.append(sty) return def appendInstantStylesheet(self, sty): """Accepts a valid StyleDOM node""" self._stylesheets.append(sty) return def runString(self, xmlString, ignorePis=0, topLevelParams=None, writer=None, baseUri='', outputStream=None): try: src = self._docReader.fromString(xmlString,stripElements=self._getWsStripElements()) except Exception, e: raise XsltException(Error.SOURCE_PARSE_ERROR, '<Python string>', e) if not ignorePis and self.checkStylesheetPis(src, baseUri): #FIXME: should we leave this to GC in Python 2.0? self._docReader.releaseNode(src) #Do it again with updates WS strip lists try: src = self._docReader.fromString(xmlString,stripElements=self._getWsStripElements()) except Exception, e: raise XsltException(Error.SOURCE_PARSE_ERROR, '<Python string>', e)
def DomConvert(node, xslParent, xslDoc, extUris, extElements, preserveSpace): if node.nodeType == Node.ELEMENT_NODE: mapping = g_mappings.get(node.namespaceURI, None) if mapping: if not mapping.has_key(node.localName): raise XsltException(Error.XSLT_ILLEGAL_ELEMENT, node.localName) xsl_class = mapping[node.localName] xsl_instance = xsl_class(xslDoc, baseUri=xslParent.baseUri) for attr in node.attributes.values(): if not attr.namespaceURI and attr.localName not in xsl_instance.__class__.legalAttrs: raise XsltException(Error.XSLT_ILLEGAL_ATTR, attr.nodeName, xsl_instance.nodeName) xsl_instance.setAttributeNS(attr.namespaceURI, attr.nodeName, attr.value) xslParent.appendChild(xsl_instance) elif node.namespaceURI in extUris: name = (node.namespaceURI, node.localName) if name in extElements.keys(): ext_class = extElements[name] else: #Default XsltElement behavior effects fallback ext_class = XsltElement xsl_instance = ext_class(xslDoc, node.namespaceURI, node.localName, node.prefix, xslParent.baseUri) for attr in node.attributes.values(): if (attr.namespaceURI, attr.localName) == (XSL_NAMESPACE, 'extension-element-prefixes'): ext_prefixes = string.splitfields(attr.value) for prefix in ext_prefixes: if prefix == '#default': prefix = '' extUris.append(node_nss[prefix]) xsl_instance.setAttributeNS(attr.namespaceURI, attr.nodeName, attr.value) xslParent.appendChild(xsl_instance) else: xsl_instance = LiteralElement(xslDoc, node.namespaceURI, node.localName, node.prefix, xslParent.baseUri) node_nss = GetAllNs(node) for attr in node.attributes.values(): if (attr.namespaceURI, attr.localName) == (XSL_NAMESPACE, 'extension-element-prefixes'): ext_prefixes = string.splitfields(attr.value) for prefix in ext_prefixes: if prefix == '#default': prefix = '' extUris.append(node_nss[prefix]) xsl_instance.setAttributeNS(attr.namespaceURI, attr.nodeName, attr.value) xslParent.appendChild(xsl_instance) ps = (xsl_instance.namespaceURI, xsl_instance.localName) == ( XSL_NAMESPACE, 'text') or xsl_instance.getAttributeNS( XML_NAMESPACE, 'space') == 'preserve' #ps = (xsl_instance.namespaceURI, xsl_instance.localName) == (XSL_NAMESPACE, 'text') for child in node.childNodes: DomConvert(child, xsl_instance, xslDoc, extUris, extElements, ps) elif node.nodeType == Node.TEXT_NODE: if string.strip(node.data) or preserveSpace: xsl_instance = LiteralText(xslDoc, node.data) xslParent.appendChild(xsl_instance) return
def FromDocument(oldDoc, baseUri='', stylesheetReader=None): #FIXME: We really shouldn't mutate the given doc, but this is the easiest way to strip whitespace if baseUri and baseUri[-1] == '/': modBaseUri = baseUri else: modBaseUri = baseUri + '/' oldDoc.normalize() extElements = xslt.g_extElements source_root = oldDoc.documentElement #Set up a new document for the stylesheet nodes if source_root.namespaceURI == XSL_NAMESPACE: if source_root.localName not in ['stylesheet', 'transform']: raise XsltException(Error.STYLESHEET_ILLEGAL_ROOT, source_root.nodeName) result_elem_root = 0 else: result_elem_root = 1 xsl_doc = createDocument() ext_uris = [] if result_elem_root: vattr = source_root.getAttributeNodeNS(XSL_NAMESPACE, 'version') if not vattr: root_nss = GetAllNs(source_root) if filter(lambda x, n=root_nss: n[x] == XSL_NAMESPACE, root_nss.keys()): raise XsltException(Error.STYLESHEET_MISSING_VERSION) else: raise XsltException(Error.STYLESHEET_MISSING_VERSION_NOTE1) sheet = StylesheetElement(xsl_doc, XSL_NAMESPACE, 'transform', vattr.prefix, baseUri) sheet.setAttributeNS(EMPTY_NAMESPACE, 'version', vattr.value) tpl = TemplateElement(xsl_doc, XSL_NAMESPACE, 'template', vattr.prefix, baseUri) tpl.setAttributeNS(EMPTY_NAMESPACE, 'match', '/') sheet.appendChild(tpl) sheet.__dict__['extensionNss'] = [] xsl_doc.appendChild(sheet) DomConvert(source_root, tpl, xsl_doc, [], extElements, 0) else: sheet = StylesheetElement(xsl_doc, source_root.prefix, source_root.localName, baseUri=baseUri) sty_nss = GetAllNs(source_root) for attr in source_root.attributes.values(): if (attr.namespaceURI, attr.localName) == ('', 'extension-element-prefixes'): ext_prefixes = string.splitfields(attr.value) for prefix in ext_prefixes: if prefix == '#default': prefix = '' ext_uris.append(sty_nss[prefix]) sheet.setAttributeNS(attr.namespaceURI, attr.nodeName, attr.value) sheet.__dict__['extensionNss'] = ext_uris if not sheet.getAttributeNS(EMPTY_NAMESPACE, 'version'): raise XsltException(Error.STYLESHEET_MISSING_VERSION) xsl_doc.appendChild(sheet) for child in source_root.childNodes: DomConvert(child, sheet, xsl_doc, ext_uris, extElements, 0) #Handle includes includes = filter( lambda x: x.nodeType == Node.ELEMENT_NODE and (x.namespaceURI, x.localName) == (XSL_NAMESPACE, 'include'), sheet.childNodes) for inc in includes: href = inc.getAttributeNS(EMPTY_NAMESPACE, 'href') if stylesheetReader is None: stylesheetReader = StylesheetReader() docfrag = stylesheetReader.fromUri(href, baseUri=baseUri, ownerDoc=xsl_doc) sty = docfrag.firstChild included_nss = GetAllNs(sty) for child in sty.childNodes[:]: if child.nodeType != Node.ELEMENT_NODE: continue sheet.insertBefore(child, inc) #migrate old nss from stylesheet directly to new child for prefix in included_nss.keys(): if prefix: child.setAttributeNS(XMLNS_NAMESPACE, 'xmlns:' + prefix, included_nss[prefix]) else: child.setAttributeNS(XMLNS_NAMESPACE, 'xmlns', included_nss[prefix]) sheet.removeChild(inc) ReleaseNode(inc) #sty.reclaim() try: sheet.setup() except: ReleaseNode(sheet.ownerDocument) raise return sheet