Checks valid reference metadata using DOI (if present).

        Args:
            isvalid_reference (`bool`): flag from schema indicating reference to be checked.
            field (`str`): 'reference'
            value (`dict`): dictionary of reference metadata.

        The rule's arguments are validated against this schema:
            {'isvalid_reference': {'type': 'bool'}, 'field': {'type': 'str'},
             'value': {'type': 'dict'}}

def _validate_isvalid_reference(self, isvalid_reference, field, value):
        """Checks valid reference metadata using DOI (if present).

        Args:
            isvalid_reference (`bool`): flag from schema indicating reference to be checked.
            field (`str`): 'reference'
            value (`dict`): dictionary of reference metadata.

        The rule's arguments are validated against this schema:
            {'isvalid_reference': {'type': 'bool'}, 'field': {'type': 'str'},
             'value': {'type': 'dict'}}

        """
        if 'doi' in value:
            try:
                ref = crossref_api.works(ids=value['doi'])['message']
            except (HTTPError, habanero.RequestError):
                self._error(field, 'DOI not found')
                return
            except ConnectionError:
                warn('network not available, DOI not validated.')
                return

            # Assume that the reference returned by the DOI lookup always has a container-title
            ref_container = ref.get('container-title')[0]
            # TODO: Add other container types: value.get('journal') or value.get('report') or ...
            # note that there's a type field in the ref that is journal-article, proceedings-article
            container = value.get('journal')
            if container is None or container != ref_container:
                self._error(field, 'journal should be {}'.format(ref_container))

            # Assume that the reference returned by DOI lookup always has a year
            ref_year = ref.get('published-print') or ref.get('published-online')
            ref_year = ref_year['date-parts'][0][0]
            year = value.get('year')
            if year is None or year != ref_year:
                self._error(field, 'year should be {}'.format(ref_year))

            # Volume number might not be in the reference
            ref_volume = ref.get('volume')
            volume = value.get('volume')
            if ref_volume is None:
                if volume is not None:
                    self._error(field, 'Volume was specified in the YAML but is not present in the '
                                'DOI reference.')
            else:
                if volume is None or int(volume) != int(ref_volume):
                    self._error(field, 'volume should be {}'.format(ref_volume))

            # Pages might not be in the reference
            ref_pages = ref.get('page')
            pages = value.get('pages')
            if ref_pages is None:
                if pages is not None:
                    self._error(field, 'Pages were specified in the YAML but are not present in '
                                'the DOI reference.')
            else:
                if pages is None or pages != ref_pages:
                    self._error(field, 'pages should be {}'.format(ref_pages))

            # check that all authors present
            authors = value['authors'][:]
            author_names = [a['name'] for a in authors]
            for author in ref['author']:
                # find using family name
                author_match = next(
                    (a for a in authors if
                     compare_name(author['given'], author['family'], a['name'])
                     ),
                    None
                    )
                # error if missing author in given reference information
                if author_match is None:
                    self._error(field, 'Missing author: ' +
                                ' '.join([author['given'], author['family']])
                                )
                else:
                    author_names.remove(author_match['name'])

                    # validate ORCID if given
                    orcid = author.get('ORCID')
                    if orcid:
                        # Crossref may give ORCID as http://orcid.org/####-####-####-####
                        # so need to strip the leading URL
                        orcid = orcid[orcid.rfind('/') + 1:]

                        if 'ORCID' in author_match:
                            if author_match['ORCID'] != orcid:
                                self._error(
                                    field, author_match['name'] + ' ORCID does ' +
                                    'not match that in reference. Reference: ' +
                                    orcid + '. Given: ' + author_match['ORCID']
                                    )
                        else:
                            # ORCID not given, suggest adding it
                            warn('ORCID ' + orcid + ' missing for ' + author_match['name'])

            # check for extra names given
            if len(author_names) > 0:
                self._error(field, 'Extra author(s) given: ' +
                            ', '.join(author_names)
                            )