Domanda

Ho trovato un codice su GitHub che utilizza la ricerca di DBPEDIA per inviare parole e ottenere URI candidati dal DBPEDIA. Il problema è: tutti gli URI vengono con la parola Category. Ad esempio, per la parola Berlin ritorna:

invece di

Se metto il primo URI (quello con la "categoria") sul browser, non mi mostra la pagina corrispondente all'argomento "History_of_berlin", mi restituisce una pagina che contiene un elenco di collegamenti e dove posso Trova il link a "history_of_berlin". Ma, se metto il secondo URI (quello senza "categoria") mi restituisce la pagina corrispondente all'argomento "history_of_berlin". Come potrei evitare di avere questi URI con la "categoria" restituita dalla ricerca?

Codice

package com.knowledgebooks.info_spiders;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.methods.GetMethod;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.*;

/**
 * Copyright Mark Watson 2008-2010. All Rights Reserved.
 * License: LGPL version 3 (http://www.gnu.org/licenses/lgpl-3.0.txt)
 */

// Use Georgi Kobilarov's DBpedia lookup web service
//    ref: http://lookup.dbpedia.org/api/search.asmx?op=KeywordSearch
//    example: http://lookup.dbpedia.org/api/search.asmx/KeywordSearch?QueryString=Flagstaff&QueryClass=XML&MaxHits=10

/**
 * Searches return results that contain any of the search terms. I am going to filter
 * the results to ignore results that do not contain all search terms.
 */


public class DBpediaLookupClient extends DefaultHandler {
  public DBpediaLookupClient(String query) throws Exception {
    this.query = query;
    HttpClient client = new HttpClient();

    String query2 = query.replaceAll(" ", "+"); // URLEncoder.encode(query, "utf-8");
    HttpMethod method =
      new GetMethod("http://lookup.dbpedia.org/api/search.asmx/KeywordSearch?QueryString=" +
        query2);
    try {
      client.executeMethod(method);
      System.out.println(method);
      InputStream ins = method.getResponseBodyAsStream();
      SAXParserFactory factory = SAXParserFactory.newInstance();
      SAXParser sax = factory.newSAXParser();
      sax.parse(ins, this);
    } catch (HttpException he) {
      System.err.println("Http error connecting to lookup.dbpedia.org");
    } catch (IOException ioe) {
      System.err.println("Unable to connect to lookup.dbpedia.org");
    }
    method.releaseConnection();
  }

  private List<Map<String, String>> variableBindings = new ArrayList<Map<String, String>>();
  private Map<String, String> tempBinding = null;
  private String lastElementName = null;

  public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
    //System.out.println("startElement " + qName);
    if (qName.equalsIgnoreCase("result")) {
      tempBinding = new HashMap<String, String>();
    }
    lastElementName = qName;
  }

  public void endElement(String uri, String localName, String qName) throws SAXException {
    //System.out.println("endElement " + qName);
    if (qName.equalsIgnoreCase("result")) {
      if (!variableBindings.contains(tempBinding) && containsSearchTerms(tempBinding))
        variableBindings.add(tempBinding);
    }
  }

  public void characters(char[] ch, int start, int length) throws SAXException {
    String s = new String(ch, start, length).trim();
    //System.out.println("characters (lastElementName='" + lastElementName + "'): " + s);
    if (s.length() > 0) {
      if ("Description".equals(lastElementName)) {
        if (tempBinding.get("Description") == null) {
          tempBinding.put("Description", s);
        }
        tempBinding.put("Description", "" + tempBinding.get("Description") + " " + s);
      }
      if ("URI".equals(lastElementName)) tempBinding.put("URI", s);
      if ("Label".equals(lastElementName)) tempBinding.put("Label", s);
    }
  }

  public List<Map<String, String>> variableBindings() {
    return variableBindings;
  }
  private boolean containsSearchTerms(Map<String, String> bindings) {
    StringBuilder sb = new StringBuilder();
    for (String value : bindings.values()) sb.append(value);  // do not need white space
    String text = sb.toString().toLowerCase();
    StringTokenizer st = new StringTokenizer(this.query);
    while (st.hasMoreTokens()) {
      if (text.indexOf(st.nextToken().toLowerCase()) == -1) {
        return false;
      }
    }
    return true;
  }
  private String query = "";
}
È stato utile?

Soluzione 2

Ho chiesto all'autore del codice, Mark Watson, un po 'di aiuto e mi ha risposto:

Puoi apportare questa semplice modifica del codice:

      //if ("URI".equals(lastElementName)) tempBinding.put("URI", s);
      if ("URI".equals(lastElementName) && s.indexOf("Category")==-1
&& tempBinding.get("URI") == null) {
        tempBinding.put("URI", s);
      }

Questa è un commento 1 riga, aggiungi i prossimi tre.

Questo è tutto!

Altri suggerimenti

Quando fai una ricerca, ad esempio, "History of Berlin", stai richiedendo un URL come

E stai tornando un risultato XML come questo:

<?xml version="1.0" encoding="utf-8"?>
<ArrayOfResult 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://lookup.dbpedia.org/">
    <Result>
        <Label>Museum für Naturkunde</Label>
        <URI>http://dbpedia.org/resource/Museum_für_Naturkunde</URI>
        <Description></Description>
        <Classes></Classes>
        <Categories></Categories>
        <Templates></Templates>
        <Redirects></Redirects>
        <Refcount>155</Refcount>
    </Result>
    <Result>
        <Label>History of Berlin</Label>
        <URI>http://dbpedia.org/resource/History_of_Berlin</URI>
        <Description>
            Berlin is the capital city of Germany. Berlin is a young city by European standards, founded in the 12th century.
        </Description>
        <Classes></Classes>
        <Categories>
            <Category>
                <Label>History of Berlin</Label>
                <URI>http://dbpedia.org/resource/Category:History_of_Berlin</URI>
            </Category>
            <Category>
                <Label>History of Germany by location</Label>
                <URI>http://dbpedia.org/resource/Category:History_of_Germany_by_location</URI>
            </Category>
        </Categories>
        <Templates></Templates>
        <Redirects></Redirects>
        <Refcount>14</Refcount>
    </Result>
</ArrayOfResult>

Hai ragione che ci siano URI elementi con categoria Uris, ad esempio,

<URI>http://dbpedia.org/resource/Category:History_of_Berlin</URI>

Ma quello che dovresti notare è che dalla radice del documento ci sono

ArrayOfResult/Result/Categories/Category/URI

elementi, mentre gli elementi che desideri sono

ArrayOfResult/Result/URI 

elementi. Devi solo elaborare il tuo XML in modo leggermente diverso; Non ottenere tutto il contenuto di tutto URI elementi, ma solo dal URI elementi che sono bambini di Result elementi. Non sono così familiare con l'analisi del sax, ma penso che il punto importante sia che una volta entrato in un Result, dovresti solo prendere il URI Se non sei entrato in un altro elemento figlio di Result.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top