Search code examples
sparqlcapitalizationwdqs

Capitalize the first letter of a result set


I have this SPARQL code that is meant to work on Wikidata:

SELECT
  ?game
  (group_concat(distinct      ?gameLabel ; separator = ", ") AS      ?gameLabels)
  (group_concat(distinct     ?genreLabel ; separator = ", ") AS     ?genreLabels)
  WHERE {
    ?game wdt:P31 wd:Q7889;
    wdt:P136 wd:Q744038.
    OPTIONAL {?game wdt:P136     ?genre}
    SERVICE wikibase:label {
      bd:serviceParam wikibase:language "en".
           ?game rdfs:label      ?gameLabel.
          ?genre rdfs:label     ?genreLabel.
    }
  }
GROUP BY $game
ORDER BY ASC (?gameLabels)

You can test the code here:

https://query.wikidata.org/

Suppose that ?genreLabel is always lower case by default. How do I capitalize the first letter of each returned value? Thanks.


Solution

  • That's the point where things are getting complicated with the magic label SERVICE of Wikidata because you can't use them in BIND parts - or least I don't know how:

    SELECT
      ?game
      (group_concat(distinct      ?gameLabel ; separator = ", ") AS      ?gameLabels)
      (group_concat(distinct     ?genreL ; separator = ", ") AS     ?genreLabels)
    
      WHERE {
        ?game wdt:P31 wd:Q7889 ;
              wdt:P136 wd:Q744038 .
        OPTIONAL {
           ?game wdt:P136     ?genre. 
           ?genre rdfs:label ?gL. 
           FILTER(LANGMATCHES(LANG(?gL), "en"))
        }
        BIND(CONCAT(UCASE(SUBSTR(?gL, 1, 1)), SUBSTR(?gL, 2)) as ?genreL)
    
        SERVICE wikibase:label {
          bd:serviceParam wikibase:language "en".
               ?game rdfs:label      ?gameLabel.
        }
    
      }
    GROUP BY ?game
    ORDER BY ASC (?gameLabels)
    

    The idea is as follows:

    • take the first character of the label: SUBSTR(?gL, 1, 1)
    • apply the upper case operator on it: UCASE(SUBSTR(?gL, 1, 1))
    • take the whole string starting from the second character: SUBSTR(?gL, 2))
    • concatenate both parts: CONCAT(UCASE(SUBSTR(?gL, 1, 1)), SUBSTR(?gL, 2))

    Note, at some point, it might be easier to do String modification and styling on the client side...