<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def read(string):
 """ Read a graph from a XML document and return it. Nodes and edges specified in the input will be added to the current graph. @type string: string @param string: Input string in XML format specifying a graph. @rtype: graph @return: Graph """

    dom = parseString(string)
    if dom.getElementsByTagName("graph"):
        G = graph()
    elif dom.getElementsByTagName("digraph"):
        G = digraph()
    elif dom.getElementsByTagName("hypergraph"):
        return read_hypergraph(string)
    else:
        raise InvalidGraphType
    
    # Read nodes...
    for each_node in dom.getElementsByTagName("node"):
        G.add_node(each_node.getAttribute('id'))
        for each_attr in each_node.getElementsByTagName("attribute"):
            G.add_node_attribute(each_node.getAttribute('id'),
                                     (each_attr.getAttribute('attr'),
                each_attr.getAttribute('value')))

    # Read edges...
    for each_edge in dom.getElementsByTagName("edge"):
        if (not G.has_edge((each_edge.getAttribute('from'), each_edge.getAttribute('to')))):
            G.add_edge((each_edge.getAttribute('from'), each_edge.getAttribute('to')), \
                wt = float(each_edge.getAttribute('wt')), label = each_edge.getAttribute('label'))
        for each_attr in each_edge.getElementsByTagName("attribute"):
            attr_tuple = (each_attr.getAttribute('attr'), each_attr.getAttribute('value'))
            if (attr_tuple not in G.edge_attributes((each_edge.getAttribute('from'), \
                each_edge.getAttribute('to')))):
                G.add_edge_attribute((each_edge.getAttribute('from'), \
                    each_edge.getAttribute('to')), attr_tuple)
    
    return G