Applies element_function to each of the sub-elements in the XML file.
    The passed in function must take at least one element, and an optional
    list of **kwarg which are relevant to each of the elements in the list:
        def elem_func(each_elem, **kwargs)

    Implements the recommended cElementTree iterparse pattern, which is
    efficient for reading in a file, making changes and writing it again.

def iterparse_elements(element_function, file_or_path, **kwargs):
    """
    Applies element_function to each of the sub-elements in the XML file.
    The passed in function must take at least one element, and an optional
    list of **kwarg which are relevant to each of the elements in the list:
        def elem_func(each_elem, **kwargs)

    Implements the recommended cElementTree iterparse pattern, which is
    efficient for reading in a file, making changes and writing it again.
    """

    if not hasattr(element_function, '__call__'):
        return

    file_path = getattr(file_or_path, 'name', file_or_path)
    context = iter(iterparse(file_path, events=('start', 'end')))
    root = None  # Capture root for Memory management

    # Start event loads child; by the End event it's ready for processing

    for event, child in context:
        if root is None:
            root = child
        if event == 'end':  # Ensures the element has been fully read
            element_function(child, **kwargs)
            root.clear()