Esempio n. 1
0
def saxify(element, producer, namespaces={}, prefixes={}):
    """Generate SAX-like events out of an lxml element. This is
    expected to be used with an XMLExport producer, that is not 100%
    pure SAX.
    """
    tag = element.tag
    if tag in (etree.Comment, etree.ProcessingInstruction):
        if element.tail:
            producer.characters(element.tail)
        return

    if prefixes and not namespaces:
        namespaces = {n: p for p, n in prefixes.items()}

    new_prefixes = []
    all_namespaces = namespaces.copy()
    all_prefixes = prefixes.copy()

    def check_namespace_prefix(namespace):
        if namespace is not None and namespace not in all_namespaces:
            prefix = namespace.rstrip('/').split('/')[-1]
            if not prefix or prefix in all_prefixes:
                prefix = 'ns{0:02}'.format(len(all_namespaces))
            new_prefixes.append((namespace, prefix))
            all_namespaces[namespace] = prefix
            all_prefixes[prefix] = namespace

    attributes_values = {}
    attributes = element.items()
    if attributes:
        for ns_name, value in attributes:
            namespace, name = _getNsTag(ns_name)
            check_namespace_prefix(namespace)
            attributes_values[(namespace, name)] = value

    tag_namespace, tag_name = _getNsTag(tag)
    check_namespace_prefix(tag_namespace)

    for namespace, prefix,  in new_prefixes:
        producer.startPrefixMapping(prefix, namespace)

    producer.startElementNS(tag_namespace, tag_name, attributes_values)
    if element.text:
        producer.characters(element.text)

    for child in element:
        saxify(child, producer, all_namespaces)

    producer.endElementNS(tag_namespace, tag_name)
    for namespace, prefix in new_prefixes:
        producer.endPrefixMapping(namespace)
    if element.tail:
        producer.characters(element.tail)
 def endElementNS(self, ns_name, qname):
     element = self._element_stack.pop()
     ns_uri, name = ns_name
     if ns_uri is None:
         ns_uri = self._default_ns
     if (ns_uri, name) != _getNsTag(element.tag):
         raise SaxError("Unexpected element closed: {%s}%s" % ns_name)
 def endElementNS(self, ns_name, qname):
     element = self._element_stack.pop()
     ns_uri, name = ns_name
     if ns_uri is None:
         ns_uri = self._default_ns
     if (ns_uri, name) != _getNsTag(element.tag):
         raise SaxError("Unexpected element closed: {%s}%s" % ns_name)