0

I wrote this Sparql query to retrieve item labels in multiple language

  SELECT ?item ?en ?es ?it  WHERE {
  { ?item wdt:P31 wd:Q6256. }
  UNION
  { ?item wdt:P31 wd:Q1250464. }
  UNION
  { ?item wdt:P31 wd:Q3624078. }
  UNION
  { ?item wdt:P31 wd:Q619610. }
  UNION
  { ?item wdt:P31 wd:Q179164. }
  UNION
  { ?item wdt:P31 wd:Q7270. }
  ?item rdfs:label ?en filter (lang(?en) = "en").
  ?item rdfs:label ?es filter (lang(?es) = "es").
  ?item rdfs:label ?it filter (lang(?it) = "it").

} LIMIT 2

that gives

{
  "item": {
    "type": "uri",
    "value": "http://www.wikidata.org/entity/Q43"
  },
  "en": {
    "xml:lang": "en",
    "type": "literal",
    "value": "Turkey"
  },
  "es": {
    "xml:lang": "es",
    "type": "literal",
    "value": "Turquía"
  },
  "it": {
    "xml:lang": "it",
    "type": "literal",
    "value": "Turchia"
  }
}

I would like now to retrieve item url for each language. An approach could be the following

SELECT ?cid ?country ?article_en  ?article_de WHERE {
    ?cid wdt:P31 wd:Q3624078 .
    OPTIONAL {
        ?cid rdfs:label ?country filter (lang(?country) = "en") .
    }
  OPTIONAL {
        ?cid rdfs:label ?country filter (lang(?country) = "de") .
    }
    OPTIONAL {
      ?article_en schema:about ?cid .
      ?article_en schema:inLanguage "en" .
      FILTER (SUBSTR(str(?article_en), 1, 25) = "https://en.wikipedia.org/")
    }
  OPTIONAL {
      ?article_de schema:about ?cid .
      ?article_de schema:inLanguage "de" .
      FILTER (SUBSTR(str(?article_de), 1, 25) = "https://de.wikipedia.org/")
    }
}

that gives

{
  "cid": {
    "type": "uri",
    "value": "http://www.wikidata.org/entity/Q236"
  },
  "article_de": {
    "type": "uri",
    "value": "https://de.wikipedia.org/wiki/Montenegro"
  },
  "article_en": {
    "type": "uri",
    "value": "https://en.wikipedia.org/wiki/Montenegro"
  },
  "country": {
    "xml:lang": "en",
    "type": "literal",
    "value": "Montenegro"
  }
}

Try it here.

This will require to have a separate property article_* for each language.

Putting all together:

SELECT ?item ?en ?es ?url_en ?url_es  WHERE { 
{ ?item wdt:P31 wd:Q43229. }
UNION { ?item wdt:P31 wd:Q4830453. }
OPTIONAL { ?item rdfs:label ?en filter (lang(?en) = "en"). }
OPTIONAL { ?item rdfs:label ?es filter (lang(?es) = "es"). }

  OPTIONAL {
      ?url_en schema:about ?item .
      ?url_en schema:inLanguage "en" .
      FILTER (SUBSTR(str(?url_en), 1, 25) = "https://en.wikipedia.org/")
    }
  
  OPTIONAL {
      ?url_es schema:about ?item .
      ?url_es schema:inLanguage "es" .
      FILTER (SUBSTR(str(?url_es), 1, 25) = "https://es.wikipedia.org/")
    }
  
} LIMIT 10

Try it here.

that gives

{
  "item": {
    "type": "uri",
    "value": "http://www.wikidata.org/entity/Q130178"
  },
  "en": {
    "xml:lang": "en",
    "type": "literal",
    "value": "Arcadie"
  },
  "es": {
    "xml:lang": "es",
    "type": "literal",
    "value": "Arcadie"
  },
  "url_en": {
    "type": "uri",
    "value": "https://en.wikipedia.org/wiki/Arcadie"
  },
  "url_es": {
    "type": "uri",
    "value": "https://es.wikipedia.org/wiki/Arcadie_(grupo)"
  }
}

Is there a way to group the url and the label property result like

{
    "en": {
        "url": {
            "xml:lang": "es",
            "type": "literal",
            "value": "Arcadie"
        },
        "label": {
            "type": "uri",
            "value": "https://es.wikipedia.org/wiki/Arcadie_(grupo)"
        }
    }
}
loretoparisi
  • 15,724
  • 11
  • 102
  • 146
  • 1
    that's not possible with the SPARQL query itself - the SPARQL JSON response format is standardized as is: https://www.w3.org/TR/sparql11-results-json/ – UninformedUser Apr 01 '22 at 06:05
  • 1
    you would need something like JSON framing, for JSON-LD format (the result would be a graph here, e.g. via CONSTRUCT query) some APIs allow for providing such frames, but I haven't seen such an option for standard SELECT queries to modify the standard SPARQL JSON result format - I guess doing it on client side would be the way to go then – UninformedUser Apr 01 '22 at 06:08
  • 1
    but maybe JSON-LD and its framing would be interesting for you nevertheless, so here is the reference to it: https://json-ld.org/spec/latest/json-ld-framing/ - and JSON-LD is closer to a domain focused JSON object anyways in my opinion, but it needs a `CONSTRUCT` query then – UninformedUser Apr 01 '22 at 06:09
  • @UninformedUser thank you for these details. I did something different when collecting entity properties like in this SELECT query here https://gist.github.com/loretoparisi/e2ccf211c4a723e83944b8a8819146e3 – loretoparisi Apr 01 '22 at 08:31

0 Answers0