U
    :gW$                     @   s   d Z ddlmZ ddlmZ ddlmZmZ ddlmZm	Z	 G dd dej
Zdd	 ZG d
d deZG dd dZdd ZdS )a?  
SAX-based adapter to copy trees from/to the Python standard library.

Use the `ElementTreeContentHandler` class to build an ElementTree from
SAX events.

Use the `ElementTreeProducer` class or the `saxify()` function to fire
the SAX events of an ElementTree against a SAX ContentHandler.

See https://lxml.de/sax.html
    )ContentHandler)etree)ElementTree
SubElement)CommentProcessingInstructionc                   @   s   e Zd ZdZdS )SaxErrorzGeneral SAX error.
    N)__name__
__module____qualname____doc__ r   r   ,/tmp/pip-unpacked-wheel-m1sofc2u/lxml/sax.pyr      s   r   c                 C   s0   | d dkr$t | dd  ddS d | fS d S )Nr   {   })tuplesplit)tagr   r   r   	_getNsTag   s    r   c                   @   s   e Zd ZdZd ddZdd ZeeejdZdd	 Zd
d Z	dd Z
dd Zdd Zdd Zd!ddZdd Zdd Zd"ddZdd Zdd ZeZdS )#ElementTreeContentHandlerz/Build an lxml ElementTree from SAX events.
    Nc                 C   sL   t |  d | _g | _g | _d | _d d gi| _i | _|d krBtj	}|| _
d S N)r   __init___root_root_siblings_element_stack_default_ns_ns_mapping_new_mappingsr   Element_makeelement)selfmakeelementr   r   r   r   %   s    
z"ElementTreeContentHandler.__init__c                 C   s
   t | jS )z=Contains the generated ElementTree after parsing is finished.)r   r   r!   r   r   r   
_get_etree1   s    z$ElementTreeContentHandler._get_etree)docc                 C   s   d S r   r   )r!   locatorr   r   r   setDocumentLocator7   s    z,ElementTreeContentHandler.setDocumentLocatorc                 C   s   d S r   r   r#   r   r   r   startDocument:   s    z'ElementTreeContentHandler.startDocumentc                 C   s   d S r   r   r#   r   r   r   endDocument=   s    z%ElementTreeContentHandler.endDocumentc                 C   sR   || j |< z| j| | W n  tk
r>   |g| j|< Y nX |d krN|| _d S r   )r   r   appendKeyErrorr   )r!   prefixurir   r   r   startPrefixMapping@   s    
z,ElementTreeContentHandler.startPrefixMappingc                 C   s(   | j | }|  |d kr$|d | _d S N)r   popr   )r!   r,   Zns_uri_listr   r   r   endPrefixMappingI   s    
z*ElementTreeContentHandler.endPrefixMappingc                 C   s4   |\}}|rd| }n| j r,d| j |f }n|}|S )N{%s}%s)r   )r!   Zns_name_tuplens_uri
local_nameel_tagr   r   r   	_buildTagO   s    
z#ElementTreeContentHandler._buildTagc                 C   s   |  |}|rni }z| }W n tk
r:   | }Y nX |D ]*\}}|d rZd| }	n|d }	|||	< q@nd }| j}
| jd kr| ||| j }| _| jrt	|dr| jD ]}|
| q| jd d = nt|
d ||| j}|
| | j  d S )Nr   r3   r   addpreviousr0   )r7   	iteritemsAttributeErroritemsr   r   r    r   r   hasattrr8   r   r*   clear)r!   ns_nameqname
attributesZel_nameattrsZiter_attributesZ
name_tuplevalue	attr_nameZelement_stackelementsiblingr   r   r   startElementNSY   s6    




 
z(ElementTreeContentHandler.startElementNSc                 C   s6   t ||}| jd kr"| j| n| jd | d S r/   )r   r   r   r*   r   )r!   targetdatapir   r   r   processingInstructionz   s    

z/ElementTreeContentHandler.processingInstructionc                 C   s.   | j  }| |}||jkr*td| d S )NzUnexpected element closed: )r   r1   r7   r   r   )r!   r>   r?   rD   r6   r   r   r   endElementNS   s    


z&ElementTreeContentHandler.endElementNSc                 C   s,   |rdd |  D }| d |f|| d S )Nc                 S   s   i | ]\}}d |f|qS r   r   ).0kvr   r   r   
<dictcomp>   s      z:ElementTreeContentHandler.startElement.<locals>.<dictcomp>)r;   rF   )r!   namer@   r   r   r   startElement   s    z&ElementTreeContentHandler.startElementc                 C   s   |  d |f| d S r   )rK   )r!   rP   r   r   r   
endElement   s    z$ElementTreeContentHandler.endElementc                 C   sP   | j d }z|d }|jpd| |_W n$ tk
rJ   |jp>d| |_Y nX d S )Nr0    )r   tail
IndexErrortext)r!   rH   Zlast_elementr   r   r   
characters   s    
z$ElementTreeContentHandler.characters)N)N)N)r	   r
   r   r   r   r$   propertyr   r'   r(   r)   r.   r2   r7   rF   rJ   rK   rQ   rR   rW   ignorableWhitespacer   r   r   r   r   "   s"   
	

!

r   c                   @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )ElementTreeProducerz5Produces SAX events for an element and children.
    c                 C   sT   z|  }W n tk
r$   |}Y nX || _|| _ddlm} || _|i i | _d S )Nr   )AttributesNSImpl)getrootr:   _element_content_handlerZxml.sax.xmlreaderr[   _attr_class_empty_attributes)r!   element_or_treecontent_handlerrD   Z
attr_classr   r   r   r      s    
zElementTreeProducer.__init__c                 C   s   | j   | j}t|drjg }| }t|dd tkrJ|| | }q&|d d d D ]}| |i  qX| |i  t|dr|	 }t|dd tkr| |i  |	 }q| j 
  d S )Ngetpreviousr   r0   getnext)r^   r(   r]   r<   rc   getattrr   r*   _recursive_saxifyrd   r)   )r!   rD   ZsiblingsrE   r   r   r   saxify   s"    





zElementTreeProducer.saxifyc                 C   s  | j }|j}|tks|tkrL|tkr4||j|j |j}|rH|| d S |j	}g }||kr|
 D ]$\}}	|||	krf|||	f qf|
 }
|
ri }i }|
D ]8\}}t|}|||< | j|d |d |d dd||< q| ||}n| j}t|\}	}| j|	|||jdd}|D ]\}}||| q||	|f|| |j}|rX|| |D ]}| || q\||	|f| |D ]\}}|| q|j}|r|| d S )Nr   r   T)preferred_prefixis_attributeF)ri   )r^   r   r   r   rJ   rG   rV   rT   rW   nsmapr;   getr*   r   _build_qnamer_   r`   r,   r.   rF   rf   rK   r2   )r!   rD   Zparent_nsmaprb   r   rT   Zelement_nsmapZnew_prefixesr,   r4   ZattribsZattr_valuesZattr_qnamesZattr_ns_namerB   Zattr_ns_tupleZsax_attributesr5   r?   r-   rV   childr   r   r   rf      sx     
         
z%ElementTreeProducer._recursive_saxifyc                    sv    d kr|S |s$| | kr$|}n: fdd| D }t|dkrN|d n|rZt|nd }|d krj|S |d | S )Nc                    s$   g | ]\}}|d k	r| kr|qS r   r   )rL   pfxr-   r4   r   r   
<listcomp>   s    z4ElementTreeProducer._build_qname.<locals>.<listcomp>r   r   :)rk   r;   lenmin)r!   r4   r5   rj   rh   ri   r,   
candidatesr   ro   r   rl      s    
z ElementTreeProducer._build_qnameN)r	   r
   r   r   r   rg   rf   rl   r   r   r   r   rZ      s
   6rZ   c                 C   s   t | | S )zlOne-shot helper to generate SAX events from an XML tree and fire
    them against a SAX ContentHandler.
    )rZ   rg   )ra   rb   r   r   r   rg     s    rg   N)r   Zxml.sax.handlerr   lxmlr   Z
lxml.etreer   r   r   r   Z	LxmlErrorr   r   r   rZ   rg   r   r   r   r   <module>   s   zs