o
    g^                     @   sB   d dl Z d dlmZ dd Zdd ZdddZd	d
 Zdd ZdS )    N)etreec                    s`   dd |  dD   sdS g  fdd|  D ]} |  }|dur-||  qdS )zIterate through the tree and replace the referened elements.

    This method replaces the nodes with an href attribute and replaces it
    with the elements it's referencing to (which have an id attribute).abs

    c                 S   s   i | ]}|j d  |qS )id)attrib).0elm r   T/home/ubuntu/webapp/venv/lib/python3.10/site-packages/zeep/wsdl/messages/multiref.py
<dictcomp>   s    z$process_multiref.<locals>.<dictcomp>z*[@id]Nc                    s^   | j d}|r$|dr$ |dd }|dur$| t|| } | D ]}| q&dS )	Recursivehref#   N)r   get
startswithappend_dereference_element)noder   objchildmultiref_objectsprocess
used_nodesr   r   r      s   


z!process_multiref.<locals>.process)xpath	getparentremove)r   parentr   r   r   process_multiref   s   
r   c                    sd    fdd| j  D }t|  j|}  }|| | |  | D ]}t	| q)|S )zMove the referenced node (source) in the main response tree (target)

    :type source: lxml.etree._Element
    :type target: lxml.etree._Element
    :rtype target: lxml.etree._Element

    c                    s    i | ]\}}| j vr||qS r   nsmapr   kvtargetr   r   r	   2   s     z(_dereference_element.<locals>.<dictcomp>)
r   items_clone_elementtagr   insertindexr   iter_prefix_node)sourcer$   specific_nsmapnewr   r   r   r#   r   r   *   s   

r   c                 C   sp   |p| j }|du r| jn|}tj||d}| D ]}t|}|| q| j|_t| D ]
\}}||| q+|S )zClone the given node and return it.

    This is a recursive call since we want to clone the children the same
    way.

    :type source: lxml.etree._Element
    :type tag_name: str
    :type nsmap: dict
    :rtype source: lxml.etree._Element

    Nr   )	r'   r   r   Elementr&   r   text_get_attributesset)r   tag_namer   r.   r   	new_childkeyvaluer   r   r   r&   B   s   
r&   c                 C   s   dd | j  D }td}| j D ]*\}}|dr>||}|s%q| \}}||v r>d|||f }| 	|| qdS )a\  Translate the internal attribute values back to prefixed tokens.

    This reverses the translation done in _get_attributes

    For example::

        {
            'foo:type': '{http://example.com}string'
        }

    will be converted to:

        {
            'foo:type': 'example:string'
        }

    :type node: lxml.etree._Element

    c                 S   s   i | ]\}}||qS r   r   r    r   r   r   r	   q   s    z _prefix_node.<locals>.<dictcomp>z^{([^}]+)}(.*){z%s:%sN)
r   r%   recompiler   r   matchgroupsr   r2   )r   reverse_nsmap	prefix_rer5   r6   r:   	namespace	localnamer   r   r   r+   ]   s   


r+   c                 C   sj   | j }i }| j D ]$\}}|ddkr*|d\}}||v r*|| }d||f }|||< q
t| S )a@  Return the node attributes where prefixed values are dereferenced.

    For example the following xml::

        <foobar xmlns:xsi="foo" xmlns:ns0="bar" xsi:type="ns0:string">

    will return the dict::

        {
            'foo:type': '{http://example.com}string'
        }

    :type node: lxml.etree._Element

    :r   z{%s}%s)r   r   r%   countsplitlist)r   r   resultr5   r6   prefixr?   r>   r   r   r   r1      s   
r1   )NN)r8   lxmlr   r   r   r&   r+   r1   r   r   r   r   <module>   s    $
$