문제

GitHub에서 DBPEDIA 조회를 사용하여 단어를 보내고 DBPEDIA에서 후보 URI를 얻는 코드를 찾았습니다. 문제는 : 모든 uris는 단어와 함께 제공됩니다. Category. 예를 들어, 단어의 경우 Berlin 반환 :

대신에

브라우저에 첫 번째 URI ( "카테고리"가있는 것)를 넣으면 "history_of_berlin"주제에 해당하는 페이지를 표시하지 않으면 링크 목록이 포함 된 페이지와 내가 할 수있는 위치를 반환합니다. "history_of_berlin"에 대한 링크를 찾으십시오. 그러나 두 번째 URI ( "카테고리"가없는 것)를 넣으면 "history_of_berlin"주제에 해당하는 페이지를 반환합니다. 조회에서 "카테고리"가 반환되는이 URI를 피할 수있는 방법은 무엇입니까?

암호

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 = "";
}
도움이 되었습니까?

해결책 2

나는 코드의 저자 인 Mark Watson에게 도움을 요청했고 그는 나에게 대답했다.

이 간단한 코드를 변경할 수 있습니다.

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

그것은 1 줄에 주석입니다. 다음 세를 추가하십시오.

그게 다야!

다른 팁

"베를린의 역사"를 검색하면 URL을 요청하고 있습니다.

그리고 당신은 다음과 같은 XML 결과를 돌려 받고 있습니다.

<?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>

당신은 옳습니다 URI 카테고리 URI, 예를 들어, 예를 들어,

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

그러나 주목해야 할 것은 문서의 근원에서

ArrayOfResult/Result/Categories/Category/URI

당신이 원하는 요소는 요소입니다

ArrayOfResult/Result/URI 

집단. XML을 조금 다르게 처리하면됩니다. 얻지 마십시오 모두 의 내용 모두 URI 요소, 그러나 URI 자녀 인 요소 Result 집단. 나는 Sax Parsing에 익숙하지는 않지만 중요한 점은 일단 당신이 일단 입력 한 것입니다. Result, 당신은 만 잡아야합니다 URI 다른 자식 요소에 들어 가지 않았다면 Result.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top