def variable_element(tagname, namespaces, attributes): # required `name` attribute try: name = attributes[None, 'name'] except KeyError: raise XUpdateError(XUpdateError.MISSING_REQUIRED_ATTRIBUTE, element=tagname, attribute='name') else: if not isqname(name): raise XUpdateError(XUpdateError.INVALID_QNAME_ATTR, attribute='name', value=name) prefix, name = splitqname(name) if prefix: try: namespace = namespaces[prefix] except KeyError: raise XUpdateError(XUpdateError.UNDEFINED_PREFIX, prefix=prefix) else: namespace = None name = (namespace, name) # optional `select` attribute if (None, 'select') in attributes: select = attributes[None, 'select'] try: select = parse_expression(select) except XPathError, error: raise XUpdateError(XUpdateError.SYNTAX_ERROR, expression=select, text=str(error))
def modifications_element(tagname, namespaces, attributes): try: version = attributes[None, 'version'] except KeyError: raise XUpdateError(XUpdateError.MISSING_REQUIRED_ATTRIBUTE, element=tagname, attribute='version') else: if version != '1.0': raise XUpdateError(XUpdateError.UNSUPPORTED_VERSION, version=version) return commands.modifications_list()
def value_of_element(tagname, namespaces, attributes): # required `select` attribute try: select = attributes[None, 'select'] except KeyError: raise XUpdateError(XUpdateError.MISSING_REQUIRED_ATTRIBUTE, element=tagname, attribute='select') else: try: select = parse_expression(select) except XPathError, error: raise XUpdateError(XUpdateError.SYNTAX_ERROR, expression=select, text=str(error))
def instantiate(self, context): context.namespaces = self.namespaces targets = self.select.evaluate_as_nodeset(context) if not targets: raise XUpdateError(XUpdateError.INVALID_SELECT) for target in targets: if target.xml_type == tree.element.xml_type: context.push_tree_writer(target.xml_base) for primitive in self: primitive.instantiate(context) writer = context.pop_writer() tr = writer.get_result() while target.xml_first_child: target.xml_remove(target.xml_first_child) while tr.xml_first_child: target.xml_append(tr.xml_first_child) elif target.xml_type in (tree.attribute.xml_type, tree.text.xml_type, tree.comment.xml_type, tree.processing_instruction.xml_type): context.push_string_writer(errors=False) for primitive in self: primitive.instantiate(context) writer = context.pop_writer() value = writer.get_result() if not value and target.xml_type == tree.text.xml_type: target.xml_parent.xml_remove(target) else: target.xml_value = value return
def instantiate(self, context): context.namespaces = self.namespaces targets = self.select.evaluate_as_nodeset(context) if not targets: raise XUpdateError(XUpdateError.INVALID_SELECT) for target in targets: context.push_tree_writer(target.xml_base) for primitive in self: primitive.instantiate(context) writer = context.pop_writer() tr = writer.get_result() if self.child: focus = context.node, context.position, context.size try: context.node = target context.position = 1 size = context.size = len(target.xml_children) position = int(self.child.evaluate_as_number(context)) finally: context.node, context.position, context.size = focus if position < size: refnode = target.xml_children[position] else: refnode = None else: refnode = None while tr.xml_first_child: if refnode is not None: offset = target.xml_index(refnode) target.xml_insert(offset, tr.xml_first_child) else: target.xml_append(tr.xml_first_child) return
def evaluate_as_string(self, context): result = self._evaluate(context) if result in (XML_NAMESPACE, XMLNS_NAMESPACE): raise XUpdateError(XUpdateError.INVALID_NSURI_ATTR, attribute=self._name, value=result) return result
def instantiate(self, context): context.push_string_writer(errors=False) for primitive in self: primitive.instantiate(context) writer = context.pop_writer() name = writer.get_result() prefix, local = splitqname(name) if prefix: namespace = self.namespaces[prefix] else: namespace = None context.namespaces = self.namespaces targets = self.select.evaluate_as_nodeset(context) if not targets: raise XUpdateError(XUpdateError.INVALID_SELECT) for target in targets: parent = target.xml_parent if target.xml_type == tree.attribute.xml_type: parent.xml_attributes[namespace, name] = target.xml_value elif target.xml_type == tree.processing_instruction.xml_type: pi = tree.processing_instruction(name, target.xml_data) parent.xml_replace-child(pi, target) elif target.xml_type == tree.element.xml_type: #FIXME: Use regular constructor. No more DOM factory element = tree.element(namespace, name) # Copy any existing attributes to the newly created element if target.xml_attributes: for (ns, qname), value in target.xml_attributes.iteritems(): element.xml_attributes[ns, qname] = value # Now copy any children as well while target.xml_first_child: element.xml_append(target.xml_first_child) parent.xml_replace(target, element) return
def evaluate_as_string(self, context): result = self._evaluate(context) if not isncname(result): raise XUpdateError(XUpdateError.INVALID_NCNAME_ATTR, attribute=self._name, value=result) return result
def __init__(self, name, value): self._name = name try: avt_expression.__init__(self, value) except XsltError, error: raise XUpdateError(XUpdateError.SYNTAX_ERROR, expression=value, text=str(error))
def start_element(self, expandedName, tagName, namespaces, attributes): parent_state = self._state_stack[-1] # update in-scope namespaces (copy-on-demand) if namespaces: inscope_namespaces = parent_state.namespaces.copy() inscope_namespaces.update(namespaces) else: inscope_namespaces = parent_state.namespaces # get the class defining this element namespace, local = expandedName if namespace == XUPDATE_NAMESPACE: try: factory, validation = self._dispatch[local] except KeyError: raise XUpdateError(XUpdateError.ILLEGAL_ELEMENT, element=tagName) else: item = factory(tagName, inscope_namespaces, attributes) validation_event = expandedName else: qname = attributes.getQNameByName attrs = [(name[0], qname(name), attributes[name]) for name in attributes] item = instructions.literal_element(tagName, namespace, attrs) validation = _template_model validation_event = _literal_event # verify that this element can be declared here try: next = parent_state.validation[validation_event] except KeyError: raise XUpdateError(XUpdateError.ILLEGAL_ELEMENT_CHILD, element=parent_state.name, child=tagName) else: # save the new state for the next event check parent_state.validation = next new_state = handler_state(item, tagName, inscope_namespaces, validation) self._push_state(new_state) return
def processing_instruction_element(tagname, namespaces, attributes): # required `name` attribute try: name = attributes[None, 'name'] except KeyError: raise XUpdateError(XUpdateError.MISSING_REQUIRED_ATTRIBUTE, element=tagname, attribute='name') else: name = ncname_avt('name', name) return instructions.processing_instruction_instruction(namespaces, name)
def characters(self, data): current_state = self._state_stack[-1] # verify that the current node can have text content is_whitespace = (data.strip() == '') if not is_whitespace: try: next = current_state.validation[_text_event] except KeyError: raise XUpdateError(XUpdateError.INVALID_TEXT, element=current_state.name) else: current_state.validation = next current_state.item.append(instructions.literal_text(data))
def attribute_element(tagname, namespaces, attributes): # required `name` attribute try: name = attributes[None, 'name'] except KeyError: raise XUpdateError(XUpdateError.MISSING_REQUIRED_ATTRIBUTE, element=tagname, attribute='name') else: name = qname_avt('name', name) # optional `namespace` attribute if (None, 'namespace') in attributes: namespace = namespace_avt(attributes[None, 'namespace']) else: namespace = None return instructions.attribute_instruction(namespaces, name, namespace)
def end_element(self, expandedName, tagName): current_state = self._state_stack[-1] del self._state_stack[-1] parent_state = self._state_stack[-1] item = current_state.item # verify that the element has all required content try: current_state.validation[_end_event] except KeyError: raise XUpdateError(XUpdateError.INCOMPLETE_ELEMENT, element=tagName) ## let the XUpdate primitive perform any add'l setup, if needed #if item.has_setup: # item.setup() # update parent state parent_state.item.append(item) return
def instantiate(self, context): context.namespaces = self.namespaces name = self.name.evaluate_as_string(context) if self.namespace: namespace = self.namespace.evaluate_as_string(context) else: prefix, local = splitqname(name) try: namespace = self.namespaces[prefix] except KeyError: if not prefix: prefix = '#default' raise XUpdateError(XUpdateError.UNDEFINED_PREFIX, prefix=prefix) context.start_element(name, namespace) for child in self: child.instantiate(context) context.end_element(name, namespace) return
def instantiate(self, context): context.namespaces = self.namespaces name = self.name.evaluate_as_string(context) if self.namespace: namespace = self.namespace.evaluate_as_string(context) else: prefix, local = splitqname(name) if prefix: try: namespace = self.namespaces[prefix] except KeyError: raise XUpdateError(XUpdateError.UNDEFINED_PREFIX, prefix=prefix) else: namespace = None context.push_string_writer(errors=False) for child in self: child.instantiate(context) writer = context.pop_writer() context.attribute(name, writer.get_result(), namespace) return
attribute='select') else: try: select = parse_expression(select) except XPathError, error: raise XUpdateError(XUpdateError.SYNTAX_ERROR, expression=select, text=str(error)) # optional `child` attribute if (None, 'child') in attributes: child = attributes[None, 'child'] try: child = parse_expression(child) except XPathError, error: raise XUpdateError(XUpdateError.SYNTAX_ERROR, expression=child, text=str(error)) else: child = None return commands.append_command(namespaces, select, child) @autodispatch('update', _char_template_model) def update_element(tagname, namespaces, attributes): # required `select` attribute try: select = attributes[None, 'select'] except KeyError: raise XUpdateError(XUpdateError.MISSING_REQUIRED_ATTRIBUTE, element=tagname, attribute='select')