Esempio n. 1
0
 def __init__(self, tool, param):
     self.tool = tool
     self.name = param.get("name")
     self.label = util.xml_text(param, "label")
     self.help = util.xml_text(param, "help")
     self.html = "no html set"
     self.validators = []
     for elem in param.findall("validator"):
         self.validators.append(validation.Validator.from_element(elem))
Esempio n. 2
0
 def __init__( self, tool, param ):
     self.tool = tool
     self.name = param.get("name")
     self.label = util.xml_text(param, "label")
     self.help = util.xml_text(param, "help")
     self.html = "no html set"
     self.validators = []
     for elem in param.findall("validator"):
         self.validators.append( validation.Validator.from_element( elem ) )
Esempio n. 3
0
def parse_requirements_from_xml(xml_root):
    """

    >>> from xml.etree import ElementTree
    >>> def load_requirements( contents ):
    ...     contents_document = '''<tool><requirements>%s</requirements></tool>'''
    ...     root = ElementTree.fromstring( contents_document % contents )
    ...     return parse_requirements_from_xml( root )
    >>> reqs, containers = load_requirements('''<requirement>bwa</requirement>''')
    >>> reqs[0].name
    'bwa'
    >>> reqs[0].version is None
    True
    >>> reqs[0].type
    'package'
    >>> reqs, containers = load_requirements('''<requirement type="binary" version="1.3.3">cufflinks</requirement>''')
    >>> reqs[0].name
    'cufflinks'
    >>> reqs[0].version
    '1.3.3'
    >>> reqs[0].type
    'binary'
    """
    requirements_elem = xml_root.find("requirements")

    requirement_elems = []
    if requirements_elem is not None:
        requirement_elems = requirements_elem.findall('requirement')

    requirements = []
    for requirement_elem in requirement_elems:
        name = xml_text(requirement_elem)
        type = requirement_elem.get("type", DEFAULT_REQUIREMENT_TYPE)
        version = requirement_elem.get("version", DEFAULT_REQUIREMENT_VERSION)
        requirement = ToolRequirement(name=name, type=type, version=version)
        requirements.append(requirement)

    container_elems = []
    if requirements_elem is not None:
        container_elems = requirements_elem.findall('container')

    containers = []
    for container_elem in container_elems:
        identifier = xml_text(container_elem)
        type = container_elem.get("type", DEFAULT_CONTAINER_TYPE)
        container = ContainerDescription(identifier=identifier, type=type)
        containers.append(container)

    return requirements, containers
def parse_requirements_from_xml( xml_root ):
    """

    >>> from xml.etree import ElementTree
    >>> def load_requirements( contents ):
    ...     contents_document = '''<tool><requirements>%s</requirements></tool>'''
    ...     root = ElementTree.fromstring( contents_document % contents )
    ...     return parse_requirements_from_xml( root )
    >>> reqs, containers = load_requirements('''<requirement>bwa</requirement>''')
    >>> reqs[0].name
    'bwa'
    >>> reqs[0].version is None
    True
    >>> reqs[0].type
    'package'
    >>> reqs, containers = load_requirements('''<requirement type="binary" version="1.3.3">cufflinks</requirement>''')
    >>> reqs[0].name
    'cufflinks'
    >>> reqs[0].version
    '1.3.3'
    >>> reqs[0].type
    'binary'
    """
    requirements_elem = xml_root.find( "requirements" )

    requirement_elems = []
    if requirements_elem is not None:
        requirement_elems = requirements_elem.findall( 'requirement' )

    requirements = []
    for requirement_elem in requirement_elems:
        name = xml_text( requirement_elem )
        type = requirement_elem.get( "type", DEFAULT_REQUIREMENT_TYPE )
        version = requirement_elem.get( "version", DEFAULT_REQUIREMENT_VERSION )
        requirement = ToolRequirement( name=name, type=type, version=version )
        requirements.append( requirement )

    container_elems = []
    if requirements_elem is not None:
        container_elems = requirements_elem.findall( 'container' )

    containers = []
    for container_elem in container_elems:
        identifier = xml_text( container_elem )
        type = container_elem.get( "type", DEFAULT_CONTAINER_TYPE )
        container = ContainerDescription( identifier=identifier, type=type )
        containers.append( container )

    return requirements, containers
Esempio n. 5
0
 def _parse_output(
     self,
     data_elem,
     tool,
     default_format="data",
     default_format_source=None,
     default_metadata_source="",
 ):
     output = ToolOutput(data_elem.get("name"))
     output_format = data_elem.get("format", default_format)
     auto_format = string_as_bool(data_elem.get("auto_format", "false"))
     if auto_format and output_format != "data":
         raise ValueError("Setting format and auto_format is not supported at this time.")
     elif auto_format:
         output_format = "_sniff_"
     output.format = output_format
     output.change_format = data_elem.findall("change_format")
     output.format_source = data_elem.get("format_source", default_format_source)
     output.default_identifier_source = data_elem.get("default_identifier_source", 'None')
     output.metadata_source = data_elem.get("metadata_source", default_metadata_source)
     output.parent = data_elem.get("parent", None)
     output.label = xml_text(data_elem, "label")
     output.count = int(data_elem.get("count", 1))
     output.filters = data_elem.findall('filter')
     output.tool = tool
     output.from_work_dir = data_elem.get("from_work_dir", None)
     output.hidden = string_as_bool(data_elem.get("hidden", ""))
     output.actions = ToolOutputActionGroup(output, data_elem.find('actions'))
     output.dataset_collector_descriptions = dataset_collector_descriptions_from_elem(data_elem, legacy=self.legacy_defaults)
     return output
    def parse_column_spec(self, config_element):
        """
        Parse column definitions, which can either be a set of 'column' elements
        with a name and index (as in dynamic options config), or a shorthand
        comma separated list of names in order as the text of a 'column_names'
        element.

        A column named 'value' is required.
        """
        self.columns = {}
        if config_element.find('columns') is not None:
            column_names = util.xml_text(config_element.find('columns'))
            column_names = [n.strip() for n in column_names.split(',')]
            for index, name in enumerate(column_names):
                self.columns[name] = index
                self.largest_index = index
        else:
            self.largest_index = 0
            for column_elem in config_element.findall('column'):
                name = column_elem.get('name', None)
                assert name is not None, "Required 'name' attribute missing from column def"
                index = column_elem.get('index', None)
                assert index is not None, "Required 'index' attribute missing from column def"
                index = int(index)
                self.columns[name] = index
                if index > self.largest_index:
                    self.largest_index = index
                empty_field_value = column_elem.get('empty_field_value', None)
                if empty_field_value is not None:
                    self.empty_field_values[name] = empty_field_value
        assert 'value' in self.columns, "Required 'value' column missing from column def"
        if 'name' not in self.columns:
            self.columns['name'] = self.columns['value']
Esempio n. 7
0
        def _parse_collection(collection_elem):
            name = collection_elem.get("name")
            label = xml_text(collection_elem, "label")
            default_format = collection_elem.get("format", "data")
            collection_type = collection_elem.get("type", None)
            collection_type_source = collection_elem.get("type_source", None)
            collection_type_from_rules = collection_elem.get(
                "type_from_rules", None)
            structured_like = collection_elem.get("structured_like", None)
            inherit_format = False
            inherit_metadata = False
            if structured_like:
                inherit_format = string_as_bool(
                    collection_elem.get("inherit_format", None))
                inherit_metadata = string_as_bool(
                    collection_elem.get("inherit_metadata", None))
            default_format_source = collection_elem.get("format_source", None)
            default_metadata_source = collection_elem.get(
                "metadata_source", "")
            filters = collection_elem.findall('filter')

            dataset_collector_descriptions = None
            if collection_elem.find("discover_datasets") is not None:
                dataset_collector_descriptions = dataset_collector_descriptions_from_elem(
                    collection_elem, legacy=False)
            structure = ToolOutputCollectionStructure(
                collection_type=collection_type,
                collection_type_source=collection_type_source,
                collection_type_from_rules=collection_type_from_rules,
                structured_like=structured_like,
                dataset_collector_descriptions=dataset_collector_descriptions,
            )
            output_collection = ToolOutputCollection(
                name,
                structure,
                label=label,
                filters=filters,
                default_format=default_format,
                inherit_format=inherit_format,
                inherit_metadata=inherit_metadata,
                default_format_source=default_format_source,
                default_metadata_source=default_metadata_source,
            )
            outputs[output_collection.name] = output_collection

            for data_elem in collection_elem.findall("data"):
                _parse(
                    data_elem,
                    default_format=default_format,
                    default_format_source=default_format_source,
                    default_metadata_source=default_metadata_source,
                )

            for data_elem in collection_elem.findall("data"):
                output_name = data_elem.get("name")
                data = data_dict[output_name]
                assert data
                del data_dict[output_name]
                output_collection.outputs[output_name] = data
            output_collections[name] = output_collection
Esempio n. 8
0
 def _parse_output(
     self,
     data_elem,
     tool,
     default_format="data",
     default_format_source=None,
     default_metadata_source="",
 ):
     output = ToolOutput( data_elem.get("name") )
     output_format = data_elem.get("format", default_format)
     auto_format = string_as_bool( data_elem.get( "auto_format", "false" ) )
     if auto_format and output_format != "data":
         raise ValueError("Setting format and auto_format is not supported at this time.")
     elif auto_format:
         output_format = "_sniff_"
     output.format = output_format
     output.change_format = data_elem.findall("change_format")
     output.format_source = data_elem.get("format_source", default_format_source)
     output.metadata_source = data_elem.get("metadata_source", default_metadata_source)
     output.parent = data_elem.get("parent", None)
     output.label = xml_text( data_elem, "label" )
     output.count = int( data_elem.get("count", 1) )
     output.filters = data_elem.findall( 'filter' )
     output.tool = tool
     output.from_work_dir = data_elem.get("from_work_dir", None)
     output.hidden = string_as_bool( data_elem.get("hidden", "") )
     output.actions = ToolOutputActionGroup( output, data_elem.find( 'actions' ) )
     output.dataset_collector_descriptions = dataset_collector_descriptions_from_elem( data_elem, legacy=self.legacy_defaults )
     return output
Esempio n. 9
0
    def parse_column_spec(self, config_element):
        """
        Parse column definitions, which can either be a set of 'column' elements
        with a name and index (as in dynamic options config), or a shorthand
        comma separated list of names in order as the text of a 'column_names'
        element.

        A column named 'value' is required.
        """
        self.columns = {}
        if config_element.find('columns') is not None:
            column_names = util.xml_text(config_element.find('columns'))
            column_names = [n.strip() for n in column_names.split(',')]
            for index, name in enumerate(column_names):
                self.columns[name] = index
                self.largest_index = index
        else:
            self.largest_index = 0
            for column_elem in config_element.findall('column'):
                name = column_elem.get('name', None)
                assert name is not None, "Required 'name' attribute missing from column def"
                index = column_elem.get('index', None)
                assert index is not None, "Required 'index' attribute missing from column def"
                index = int(index)
                self.columns[name] = index
                if index > self.largest_index:
                    self.largest_index = index
                empty_field_value = column_elem.get('empty_field_value', None)
                if empty_field_value is not None:
                    self.empty_field_values[name] = empty_field_value
        assert 'value' in self.columns, "Required 'value' column missing from column def"
        if 'name' not in self.columns:
            self.columns['name'] = self.columns['value']
 def parse( self, root ):
     # Get the name 
     self.name = root.get( "name" )
     if not self.name: 
         raise Exception, "Missing external_service_type 'name'"
     # Get the UNIQUE id for the tool 
     self.id = root.get( "id" )
     if not self.id: 
         raise Exception, "Missing external_service_type 'id'"
     self.config_version = root.get( "version" )
     if not self.config_version: 
         self.config_version = '1.0.0'
     self.description = util.xml_text(root, "description")
     self.version = util.xml_text( root.find( "version" ) )
     # parse the form
     self.form_definition = form_factory.from_elem( root.find( 'form' ) )
     self.parse_data_transfer_settings( root )
     self.parse_run_details( root )
     #external services actions
     self.actions = ExternalServiceActionsGroup.from_elem( root.find( 'actions' ), parent=self )
Esempio n. 11
0
 def parse( self, root ):
     # Get the name
     self.name = root.get( "name" )
     if not self.name:
         raise Exception( "Missing external_service_type 'name'" )
     # Get the UNIQUE id for the tool
     self.id = root.get( "id" )
     if not self.id:
         raise Exception( "Missing external_service_type 'id'" )
     self.config_version = root.get( "version" )
     if not self.config_version:
         self.config_version = '1.0.0'
     self.description = util.xml_text(root, "description")
     self.version = util.xml_text( root.find( "version" ) )
     # parse the form
     self.form_definition = form_factory.from_elem( root.find( 'form' ) )
     self.parse_data_transfer_settings( root )
     self.parse_run_details( root )
     # external services actions
     self.actions = ExternalServiceActionsGroup.from_elem( root.find( 'actions' ), parent=self )
Esempio n. 12
0
def container_from_element(container_elem):
    identifier = xml_text(container_elem)
    type = container_elem.get("type", DEFAULT_CONTAINER_TYPE)
    resolve_dependencies = asbool(container_elem.get("resolve_dependencies", DEFAULT_CONTAINER_RESOLVE_DEPENDENCIES))
    shell = container_elem.get("shell", DEFAULT_CONTAINER_SHELL)
    container = ContainerDescription(
        identifier=identifier,
        type=type,
        resolve_dependencies=resolve_dependencies,
        shell=shell,
    )
    return container
Esempio n. 13
0
def container_from_element(container_elem):
    identifier = xml_text(container_elem)
    type = container_elem.get("type", DEFAULT_CONTAINER_TYPE)
    resolve_dependencies = asbool(container_elem.get("resolve_dependencies", DEFAULT_CONTAINER_RESOLVE_DEPENDENCIES))
    shell = container_elem.get("shell", DEFAULT_CONTAINER_SHELL)
    container = ContainerDescription(
        identifier=identifier,
        type=type,
        resolve_dependencies=resolve_dependencies,
        shell=shell,
    )
    return container
Esempio n. 14
0
    def _parse_expression_output(self, output_elem, tool, **kwds):
        output_type = output_elem.get("type")
        from_expression = output_elem.get("from")
        output = ToolExpressionOutput(
            output_elem.get("name"),
            output_type,
            from_expression,
        )
        output.path = output_elem.get("value")
        output.label = xml_text(output_elem, "label")

        output.hidden = string_as_bool(output_elem.get("hidden", ""))
        output.actions = ToolOutputActionGroup(output, output_elem.find('actions'))
        output.dataset_collector_descriptions = []
        return output
Esempio n. 15
0
def parse_requirements_from_xml(xml_root):
    """

    >>> from galaxy.util import parse_xml_string
    >>> def load_requirements(contents):
    ...     contents_document = '''<tool><requirements>%s</requirements></tool>'''
    ...     root = parse_xml_string(contents_document % contents)
    ...     return parse_requirements_from_xml(root)
    >>> reqs, containers = load_requirements('''<requirement>bwa</requirement>''')
    >>> reqs[0].name
    'bwa'
    >>> reqs[0].version is None
    True
    >>> reqs[0].type
    'package'
    >>> reqs, containers = load_requirements('''<requirement type="binary" version="1.3.3">cufflinks</requirement>''')
    >>> reqs[0].name
    'cufflinks'
    >>> reqs[0].version
    '1.3.3'
    >>> reqs[0].type
    'binary'
    """
    requirements_elem = xml_root.find("requirements")

    requirement_elems = []
    if requirements_elem is not None:
        requirement_elems = requirements_elem.findall('requirement')

    requirements = ToolRequirements()
    for requirement_elem in requirement_elems:
        name = xml_text(requirement_elem)
        type = requirement_elem.get("type", DEFAULT_REQUIREMENT_TYPE)
        version = requirement_elem.get("version", DEFAULT_REQUIREMENT_VERSION)
        requirement = ToolRequirement(name=name, type=type, version=version)
        requirements.append(requirement)

    container_elems = []
    if requirements_elem is not None:
        container_elems = requirements_elem.findall('container')

    containers = [container_from_element(c) for c in container_elems]

    return requirements, containers
Esempio n. 16
0
 def _parse_output(
     self,
     data_elem,
     tool,
     default_format="data",
     default_format_source=None,
     default_metadata_source="",
 ):
     output = galaxy.tools.ToolOutput( data_elem.get("name") )
     output.format = data_elem.get("format", default_format)
     output.change_format = data_elem.findall("change_format")
     output.format_source = data_elem.get("format_source", default_format_source)
     output.metadata_source = data_elem.get("metadata_source", default_metadata_source)
     output.parent = data_elem.get("parent", None)
     output.label = xml_text( data_elem, "label" )
     output.count = int( data_elem.get("count", 1) )
     output.filters = data_elem.findall( 'filter' )
     output.tool = tool
     output.from_work_dir = data_elem.get("from_work_dir", None)
     output.hidden = string_as_bool( data_elem.get("hidden", "") )
     output.actions = galaxy.tools.ToolOutputActionGroup( output, data_elem.find( 'actions' ) )
     output.dataset_collectors = output_collect.dataset_collectors_from_elem( data_elem )
     return output
Esempio n. 17
0
 def _parse_output(
     self,
     data_elem,
     tool,
     default_format="data",
     default_format_source=None,
     default_metadata_source="",
 ):
     output = galaxy.tools.ToolOutput( data_elem.get("name") )
     output.format = data_elem.get("format", default_format)
     output.change_format = data_elem.findall("change_format")
     output.format_source = data_elem.get("format_source", default_format_source)
     output.metadata_source = data_elem.get("metadata_source", default_metadata_source)
     output.parent = data_elem.get("parent", None)
     output.label = xml_text( data_elem, "label" )
     output.count = int( data_elem.get("count", 1) )
     output.filters = data_elem.findall( 'filter' )
     output.tool = tool
     output.from_work_dir = data_elem.get("from_work_dir", None)
     output.hidden = string_as_bool( data_elem.get("hidden", "") )
     output.actions = galaxy.tools.ToolOutputActionGroup( output, data_elem.find( 'actions' ) )
     output.dataset_collectors = output_collect.dataset_collectors_from_elem( data_elem )
     return output
Esempio n. 18
0
 def _parse_output(
     self,
     data_elem,
     tool,
     default_format="data",
     default_format_source=None,
     default_metadata_source="",
     expression_type=None,
 ):
     from_expression = data_elem.get("from")
     output = ToolOutput(data_elem.get("name"), from_expression=from_expression)
     output_format = data_elem.get("format", default_format)
     auto_format = string_as_bool(data_elem.get("auto_format", "false"))
     if auto_format and output_format != "data":
         raise ValueError("Setting format and auto_format is not supported at this time.")
     elif auto_format:
         output_format = "_sniff_"
     output.format = output_format
     output.change_format = data_elem.findall("change_format")
     output.format_source = data_elem.get("format_source", default_format_source)
     output.default_identifier_source = data_elem.get("default_identifier_source", 'None')
     output.metadata_source = data_elem.get("metadata_source", default_metadata_source)
     output.parent = data_elem.get("parent", None)
     output.label = xml_text(data_elem, "label")
     output.count = int(data_elem.get("count", 1))
     output.filters = data_elem.findall('filter')
     output.tool = tool
     output.from_work_dir = data_elem.get("from_work_dir", None)
     if output.from_work_dir and getattr(tool, 'profile', 0) < 21.09:
         # We started quoting from_work_dir outputs in 21.09.
         # Prior to quoting, trailing spaces had no effect.
         # This ensures that old tools continue to work.
         output.from_work_dir = output.from_work_dir.strip()
     output.hidden = string_as_bool(data_elem.get("hidden", ""))
     output.actions = ToolOutputActionGroup(output, data_elem.find('actions'))
     output.dataset_collector_descriptions = dataset_collector_descriptions_from_elem(data_elem, legacy=self.legacy_defaults)
     return output
Esempio n. 19
0
 def parse_help(self):
     return xml_text(self.input_elem, "help")
Esempio n. 20
0
 def parse_help(self):
     return xml_text(self.input_elem, "help")
Esempio n. 21
0
 def parse_label(self):
     return xml_text(self.input_elem, "label")
Esempio n. 22
0
 def parse_description(self):
     return xml_text(self.root, "description")
Esempio n. 23
0
    def parse_outputs(self, tool):
        out_elem = self.root.find("outputs")
        outputs = odict()
        output_collections = odict()
        if out_elem is None:
            return outputs, output_collections

        data_dict = odict()

        def _parse(data_elem, **kwds):
            output_def = self._parse_output(data_elem, tool, **kwds)
            data_dict[output_def.name] = output_def
            return output_def

        map(_parse, out_elem.findall("data"))

        for collection_elem in out_elem.findall("collection"):
            name = collection_elem.get( "name" )
            label = xml_text( collection_elem, "label" )
            default_format = collection_elem.get( "format", "data" )
            collection_type = collection_elem.get( "type", None )
            collection_type_source = collection_elem.get( "type_source", None )
            structured_like = collection_elem.get( "structured_like", None )
            inherit_format = False
            inherit_metadata = False
            if structured_like:
                inherit_format = string_as_bool( collection_elem.get( "inherit_format", None ) )
                inherit_metadata = string_as_bool( collection_elem.get( "inherit_metadata", None ) )
            default_format_source = collection_elem.get( "format_source", None )
            default_metadata_source = collection_elem.get( "metadata_source", "" )
            filters = collection_elem.findall( 'filter' )

            dataset_collector_descriptions = None
            if collection_elem.find( "discover_datasets" ) is not None:
                dataset_collector_descriptions = dataset_collector_descriptions_from_elem( collection_elem, legacy=False )
            structure = ToolOutputCollectionStructure(
                collection_type=collection_type,
                collection_type_source=collection_type_source,
                structured_like=structured_like,
                dataset_collector_descriptions=dataset_collector_descriptions,
            )
            output_collection = ToolOutputCollection(
                name,
                structure,
                label=label,
                filters=filters,
                default_format=default_format,
                inherit_format=inherit_format,
                inherit_metadata=inherit_metadata,
                default_format_source=default_format_source,
                default_metadata_source=default_metadata_source,
            )
            outputs[output_collection.name] = output_collection

            for data_elem in collection_elem.findall("data"):
                _parse(
                    data_elem,
                    default_format=default_format,
                    default_format_source=default_format_source,
                    default_metadata_source=default_metadata_source,
                )

            for data_elem in collection_elem.findall("data"):
                output_name = data_elem.get("name")
                data = data_dict[output_name]
                assert data
                del data_dict[output_name]
                output_collection.outputs[output_name] = data
            output_collections[ name ] = output_collection

        for output_def in data_dict.values():
            outputs[output_def.name] = output_def
        return outputs, output_collections
Esempio n. 24
0
 def parse_hidden(self):
     hidden = xml_text(self.root, "hidden")
     if hidden:
         hidden = string_as_bool(hidden)
     return hidden
Esempio n. 25
0
 def parse_hidden(self):
     hidden = xml_text(self.root, "hidden")
     if hidden:
         hidden = string_as_bool(hidden)
     return hidden
Esempio n. 26
0
 def parse_description(self):
     return xml_text(self.root, "description")
Esempio n. 27
0
 def parse_label(self):
     return xml_text(self.input_elem, "label")
Esempio n. 28
0
    def parse_outputs(self, tool):
        out_elem = self.root.find("outputs")
        outputs = odict()
        output_collections = odict()
        if out_elem is None:
            return outputs, output_collections

        data_dict = odict()

        def _parse(data_elem, **kwds):
            output_def = self._parse_output(data_elem, tool, **kwds)
            data_dict[output_def.name] = output_def
            return output_def

        for _ in out_elem.findall("data"):
            _parse(_)

        for collection_elem in out_elem.findall("collection"):
            name = collection_elem.get("name")
            label = xml_text(collection_elem, "label")
            default_format = collection_elem.get("format", "data")
            collection_type = collection_elem.get("type", None)
            collection_type_source = collection_elem.get("type_source", None)
            collection_type_from_rules = collection_elem.get("type_from_rules", None)
            structured_like = collection_elem.get("structured_like", None)
            inherit_format = False
            inherit_metadata = False
            if structured_like:
                inherit_format = string_as_bool(collection_elem.get("inherit_format", None))
                inherit_metadata = string_as_bool(collection_elem.get("inherit_metadata", None))
            default_format_source = collection_elem.get("format_source", None)
            default_metadata_source = collection_elem.get("metadata_source", "")
            filters = collection_elem.findall('filter')

            dataset_collector_descriptions = None
            if collection_elem.find("discover_datasets") is not None:
                dataset_collector_descriptions = dataset_collector_descriptions_from_elem(collection_elem, legacy=False)
            structure = ToolOutputCollectionStructure(
                collection_type=collection_type,
                collection_type_source=collection_type_source,
                collection_type_from_rules=collection_type_from_rules,
                structured_like=structured_like,
                dataset_collector_descriptions=dataset_collector_descriptions,
            )
            output_collection = ToolOutputCollection(
                name,
                structure,
                label=label,
                filters=filters,
                default_format=default_format,
                inherit_format=inherit_format,
                inherit_metadata=inherit_metadata,
                default_format_source=default_format_source,
                default_metadata_source=default_metadata_source,
            )
            outputs[output_collection.name] = output_collection

            for data_elem in collection_elem.findall("data"):
                _parse(
                    data_elem,
                    default_format=default_format,
                    default_format_source=default_format_source,
                    default_metadata_source=default_metadata_source,
                )

            for data_elem in collection_elem.findall("data"):
                output_name = data_elem.get("name")
                data = data_dict[output_name]
                assert data
                del data_dict[output_name]
                output_collection.outputs[output_name] = data
            output_collections[name] = output_collection

        for output_def in data_dict.values():
            outputs[output_def.name] = output_def
        return outputs, output_collections