read xml object
        :param url: contents url
        :param markup: markup provider
        :param game: MLBAM Game object
        :param players: MLBAM Players object
        :return: pitchpx.game.game.Game object

def read_xml(cls, url, markup, game, players):
        """
        read xml object
        :param url: contents url
        :param markup: markup provider
        :param game: MLBAM Game object
        :param players: MLBAM Players object
        :return: pitchpx.game.game.Game object
        """
        innings = Inning(game, players)
        base_url = "".join([url, cls.DIRECTORY])
        # hit location data
        hit_location = cls._read_hit_chart_data(
                MlbamUtil.find_xml('/'.join([base_url, cls.FILENAME_INNING_HIT]), markup)
        )

        # create for atbat & pitch data
        for inning in MlbamUtil.find_xml_all(base_url, markup, cls.TAG, cls.FILENAME_PATTERN):
            soup = MlbamUtil.find_xml("/".join([base_url, inning.get_text().strip()]), markup)
            inning_number = int(soup.inning['num'])
            for inning_type in cls.INNINGS.keys():
                inning_soup = soup.inning.find(inning_type)
                if inning_soup is None:
                    break
                innings._inning_events(inning_soup, inning_number, cls.INNINGS[inning_type], hit_location)
                innings._inning_actions(inning_soup, inning_number, cls.INNINGS[inning_type])
        return innings