Ignore:
Timestamp:
2016-07-08T19:58:16+02:00 (8 years ago)
Author:
simon04
Message:

JOSM/wikipedia: fetch multiple Wikidata labels at once

Location:
applications/editors/josm/plugins/wikipedia
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/wikipedia/src/org/wikipedia/WikipediaApp.java

    r32606 r32608  
    1010import java.util.Arrays;
    1111import java.util.Collection;
     12import java.util.Collections;
    1213import java.util.HashMap;
    1314import java.util.List;
     
    218219
    219220    static String getLabelForWikidata(String wikidataId, Locale locale, String ... preferredLanguage) {
    220         try {
    221             CheckParameterUtil.ensureThat(WIKIDATA_PATTERN.matcher(wikidataId).matches(), "Invalid Wikidata ID given");
     221        return getLabelForWikidata(Collections.singleton(wikidataId), locale, preferredLanguage).get(wikidataId);
     222    }
     223
     224    static Map<String, String> getLabelForWikidata(Collection<String> wikidataIds, Locale locale, String ... preferredLanguage) {
     225        try {
     226            for (final String wikidataId : wikidataIds) {
     227                ensureValidWikidataId(wikidataId);
     228            }
    222229            final String url = "https://www.wikidata.org/w/api.php" +
    223230                    "?action=wbgetentities" +
    224231                    "&props=labels" +
    225                     "&ids=" + wikidataId +
     232                    "&ids=" + Utils.join("|", wikidataIds) +
    226233                    "&format=xml";
    227234            final Collection<String> languages = new ArrayList<>();
     
    232239            languages.addAll(Arrays.asList(preferredLanguage));
    233240            languages.add("en");
     241            languages.add(null);
     242            final Map<String, String> r = new HashMap<>();
    234243            try (final InputStream in = HttpClient.create(new URL(url)).setReasonForRequest("Wikipedia").connect().getContent()) {
    235244                final Document xml = DOCUMENT_BUILDER.parse(in);
    236                 for (String language : languages) {
    237                     final String label = (String) X_PATH.compile("//label[@language='" + language + "']/@value")
    238                             .evaluate(xml, XPathConstants.STRING);
    239                     if (label != null && !label.isEmpty()) {
    240                          return label;
     245                for (final String wikidataId : wikidataIds) {
     246                    final Node entity = (Node) X_PATH.compile("//entity[@id='" + wikidataId + "']").evaluate(xml, XPathConstants.NODE);
     247                    for (String language : languages) {
     248                        final String label = (String) X_PATH.compile(language != null
     249                                ? "./labels/label[@language='" + language + "']/@value"
     250                                : "./labels/label/@value"
     251                        ).evaluate(entity, XPathConstants.STRING);
     252                        if (label != null && !label.isEmpty()) {
     253                            r.put(wikidataId, label);
     254                            break;
     255                        }
    241256                    }
    242257                }
    243                 final String fallBackLabel = (String) X_PATH.compile("//label/@value").evaluate(xml, XPathConstants.STRING);
    244                 return fallBackLabel == null || fallBackLabel.isEmpty() ? null : fallBackLabel;
    245             }
     258            }
     259            return r;
    246260        } catch (Exception ex) {
    247261            throw new RuntimeException(ex);
     
    409423    }
    410424
     425    static void ensureValidWikidataId(String id) {
     426        CheckParameterUtil.ensureThat(WIKIDATA_PATTERN.matcher(id).matches(), "Invalid Wikidata ID given: " + id);
     427    }
     428
    411429    public static <T> List<List<T>> partitionList(final List<T> list, final int size) {
    412430        return new AbstractList<List<T>>() {
  • applications/editors/josm/plugins/wikipedia/test/unit/org/wikipedia/WikipediaAppTest.java

    r32114 r32608  
    168168        // not found -> null
    169169        assertThat(WikipediaApp.getLabelForWikidata("Q" + Long.MAX_VALUE, Locale.ENGLISH), nullValue());
     170        final Map<String, String> twoLabels = WikipediaApp.getLabelForWikidata(Arrays.asList("Q84", "Q1741"), Locale.GERMAN);
     171        assertThat(twoLabels.get("Q84"), is("London"));
     172        assertThat(twoLabels.get("Q1741"), is("Wien"));
    170173    }
    171174
Note: See TracChangeset for help on using the changeset viewer.