docs: def dataset_from_rdf(graph, dataset=None, node=None):
      '''
      Create or update a dataset from a RDF/DCAT graph
      '''
      dataset = dataset or Dataset()
  
      if node is None:  # Assume first match is the only match
          node = graph.value(predicate=RDF.type, object=DCAT.Dataset)
  
      d = graph.resource(node)
  
      dataset.title = rdf_value(d, DCT.title)
      dataset.description = sanitize_html(d.value(DCT.description))
      dataset.frequency = frequency_from_rdf(d.value(DCT.accrualPeriodicity))
  
      acronym = rdf_value(d, SKOS.altLabel)
      if acronym:
          dataset.acronym = acronym
  
      tags = [tag.toPython() for tag in d.objects(DCAT.keyword)]
      tags += [theme.toPython() for theme in d.objects(DCAT.theme)]
      dataset.tags = list(set(tags))
  
      identifier = rdf_value(d, DCT.identifier)
      if identifier:
          dataset.extras['dct:identifier'] = identifier
  
      if isinstance(d.identifier, URIRef):
          dataset.extras['uri'] = d.identifier.toPython()
  
      dataset.temporal_coverage = temporal_from_rdf(d.value(DCT.temporal))
  
      licenses = set()
      for distrib in d.objects(DCAT.distribution | DCAT.distributions):
          resource_from_rdf(distrib, dataset)
          for predicate in DCT.license, DCT.rights:
              value = distrib.value(predicate)
              if isinstance(value, (URIRef, Literal)):
                  licenses.add(value.toPython())
              elif isinstance(value, RdfResource):
                  licenses.add(value.identifier.toPython())
  
      default_license = dataset.license or License.default()
      dataset.license = License.guess(*licenses, default=default_license)
  
      return dataset