code: def parse_xml_report(cls, conf, path):
      
      if not os.path.exists(path):
        raise cls.IvyResolveReportError('Missing expected ivy output file {}'.format(path))
  
      logger.debug("Parsing ivy report {}".format(path))
      ret = IvyInfo(conf)
      etree = ET.parse(path)
      doc = etree.getroot()
      for module in doc.findall('dependencies/module'):
        org = module.get('organisation')
        name = module.get('name')
        for revision in module.findall('revision'):
          rev = revision.get('name')
          callers = []
          for caller in revision.findall('caller'):
            callers.append(IvyModuleRef(caller.get('organisation'),
                                        caller.get('name'),
                                        caller.get('callerrev')))
  
          for artifact in revision.findall('artifacts/artifact'):
            classifier = artifact.get('extra-classifier')
            ext = artifact.get('ext')
            ivy_module_ref = IvyModuleRef(org=org, name=name, rev=rev,
                                          classifier=classifier, ext=ext)
  
            artifact_cache_path = artifact.get('location')
            ivy_module = IvyModule(ivy_module_ref, artifact_cache_path, tuple(callers))
  
            ret.add_module(ivy_module)
      return ret
docs: Parse the ivy xml report corresponding to the name passed to ivy.
  
      :API: public
  
      :param string conf: the ivy conf name (e.g. "default")
      :param string path: The path to the ivy report file.
      :returns: The info in the xml report.
      :rtype: :class:`IvyInfo`
      :raises: :class:`IvyResolveMappingError` if no report exists.