'Locate a node in a source (parent) architecture.
Given a complete source (parent) architecture (i.e. the field
`arch` in a view), and a \'spec\' node (a node in an inheriting
view that specifies the location in the source view of what
should be changed), return (if it exists) the node in the
source view matching the specification.
:param arch: a parent architecture to modify
:param spec: a modifying node in an inheriting view
:return: a node in the source matching the spec'

def locate_node(self, arch, spec):

    if (spec.tag == 'xpath'):
        nodes = arch.xpath(spec.get('expr'))
        return (nodes[0] if nodes else None)
    elif (spec.tag == 'field'):
        for node in arch.iter('field'):
            if (node.get('name') == spec.get('name')):
                return node
        return None
    for node in arch.iter(spec.tag):
        if isinstance(node, SKIPPED_ELEMENT_TYPES):
            continue
        if all(((node.get(attr) == spec.get(attr)) for attr in spec.attrib if (attr not in ('position', 'version')))):
            if (spec.get('version') and (spec.get('version') != arch.get('version'))):
                return None
            return node
    return None
