a rss/opensearch writer and an enhanced solr xml writer. The enhanced solr writer has less configuration overhead than the original writer and should by slightly faster. The rss/opensearch writer is at this time slightly incomplete compared with the already existing rss search result form YaCy and also snippets are missing at this time. To test the new interface, open for example: http://localhost:8090/solr/select?wt=rss&q=olympia The wt-code for the new result writers are= wt=rss for opensearch wt=exml for the enhanced solr xml writer. Additionally, the SRU search parameters had been added to the solr interface which can now also be used for a normal solr/xml search.pull/1/head
parent
bca4a16603
commit
a12f693ec9
@ -0,0 +1,221 @@
|
|||||||
|
/**
|
||||||
|
* FastXMLResponseWriter
|
||||||
|
* Copyright 2012 by Michael Peter Christen
|
||||||
|
* First released 06.08.2012 at http://yacy.net
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program in the file lgpl21.txt
|
||||||
|
* If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.yacy.cora.services.federated.solr;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Writer;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.apache.lucene.document.Document;
|
||||||
|
import org.apache.lucene.document.Fieldable;
|
||||||
|
import org.apache.solr.common.util.NamedList;
|
||||||
|
import org.apache.solr.common.util.SimpleOrderedMap;
|
||||||
|
import org.apache.solr.common.util.XML;
|
||||||
|
import org.apache.solr.request.SolrQueryRequest;
|
||||||
|
import org.apache.solr.response.QueryResponseWriter;
|
||||||
|
import org.apache.solr.response.SolrQueryResponse;
|
||||||
|
import org.apache.solr.schema.DateField;
|
||||||
|
import org.apache.solr.schema.FieldType;
|
||||||
|
import org.apache.solr.schema.IndexSchema;
|
||||||
|
import org.apache.solr.schema.SchemaField;
|
||||||
|
import org.apache.solr.schema.TextField;
|
||||||
|
import org.apache.solr.search.DocIterator;
|
||||||
|
import org.apache.solr.search.DocList;
|
||||||
|
import org.apache.solr.search.DocSlice;
|
||||||
|
import org.apache.solr.search.SolrIndexSearcher;
|
||||||
|
|
||||||
|
public class EnhancedXMLResponseWriter implements QueryResponseWriter {
|
||||||
|
|
||||||
|
private static final char lb = '\n';
|
||||||
|
private static final char[] XML_START = "<?xml version = \"1.0\" encoding = \"UTF-8\"?>\n<response>\n".toCharArray();
|
||||||
|
private static final char[] XML_STOP = "\n</response>\n".toCharArray();
|
||||||
|
private static final Set<String> DEFAULT_FIELD_LIST = null;
|
||||||
|
|
||||||
|
public EnhancedXMLResponseWriter() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getContentType(final SolrQueryRequest request, final SolrQueryResponse response) {
|
||||||
|
return CONTENT_TYPE_XML_UTF8;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(@SuppressWarnings("rawtypes") NamedList n) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(final Writer writer, final SolrQueryRequest request, final SolrQueryResponse rsp) throws IOException {
|
||||||
|
writer.write(XML_START);
|
||||||
|
|
||||||
|
assert rsp.getValues().get("responseHeader") != null;
|
||||||
|
assert rsp.getValues().get("response") != null;
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
SimpleOrderedMap<Object> responseHeader = (SimpleOrderedMap<Object>) rsp.getResponseHeader();
|
||||||
|
DocSlice response = (DocSlice) rsp.getValues().get("response");
|
||||||
|
writeProps(writer, "responseHeader", responseHeader); // this.writeVal("responseHeader", responseHeader);
|
||||||
|
writeDocs(writer, request, response); // this.writeVal("response", response);
|
||||||
|
|
||||||
|
writer.write(XML_STOP);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void writeProps(final Writer writer, final String name, final NamedList<?> val) throws IOException {
|
||||||
|
int sz = val.size();
|
||||||
|
if (sz <= 0) startTagClose(writer, "lst", name); else startTagOpen(writer, "lst", name);
|
||||||
|
Object v;
|
||||||
|
for (int i = 0; i < sz; i++) {
|
||||||
|
String n = val.getName(i);
|
||||||
|
v = val.getVal(i);
|
||||||
|
if (v instanceof Integer) writeTag(writer, "int", n, ((Integer) v).toString(), false);
|
||||||
|
else if (v instanceof String) writeTag(writer, "str", n, (String) v, true);
|
||||||
|
else if (v instanceof NamedList) writeProps(writer, n, (NamedList<?>) v);
|
||||||
|
}
|
||||||
|
if (sz > 0) {
|
||||||
|
writer.write("</lst>");
|
||||||
|
writer.write(lb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final void writeDocs(final Writer writer, final SolrQueryRequest request, final DocList response) throws IOException {
|
||||||
|
boolean includeScore = false;
|
||||||
|
final int sz = response.size();
|
||||||
|
writer.write("<result");
|
||||||
|
writeAttr(writer, "name", "response");
|
||||||
|
writeAttr(writer, "numFound", Long.toString(response.matches()));
|
||||||
|
writeAttr(writer, "start", Long.toString(response.offset()));
|
||||||
|
if (includeScore) {
|
||||||
|
writeAttr(writer, "maxScore", Float.toString(response.maxScore()));
|
||||||
|
}
|
||||||
|
if (sz == 0) {
|
||||||
|
writer.write("/>");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
writer.write('>'); writer.write(lb);
|
||||||
|
SolrIndexSearcher searcher = request.getSearcher();
|
||||||
|
DocIterator iterator = response.iterator();
|
||||||
|
includeScore = includeScore && response.hasScores();
|
||||||
|
IndexSchema schema = request.getSchema();
|
||||||
|
for (int i = 0; i < sz; i++) {
|
||||||
|
int id = iterator.nextDoc();
|
||||||
|
Document doc = searcher.doc(id, DEFAULT_FIELD_LIST);
|
||||||
|
writeDoc(writer, schema, null, doc, (includeScore ? iterator.score() : 0.0f), includeScore);
|
||||||
|
}
|
||||||
|
writer.write("</result>");
|
||||||
|
writer.write(lb);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final void writeDoc(final Writer writer, final IndexSchema schema, final String name, final Document doc, final float score, final boolean includeScore) throws IOException {
|
||||||
|
startTagOpen(writer, "doc", name);
|
||||||
|
|
||||||
|
if (includeScore) {
|
||||||
|
writeTag(writer, "float", "score", Float.toString(score), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Fieldable> fields = doc.getFields();
|
||||||
|
int sz = fields.size();
|
||||||
|
int fidx1 = 0, fidx2 = 0;
|
||||||
|
while (fidx1 < sz) {
|
||||||
|
Fieldable f1 = fields.get(fidx1);
|
||||||
|
String fieldName = f1.name();
|
||||||
|
fidx2 = fidx1 + 1;
|
||||||
|
while (fidx2 < sz && fieldName.equals(fields.get(fidx2).name())) {
|
||||||
|
fidx2++;
|
||||||
|
}
|
||||||
|
SchemaField sf = schema.getFieldOrNull(fieldName);
|
||||||
|
if (sf == null) {
|
||||||
|
sf = new SchemaField(fieldName, new TextField());
|
||||||
|
}
|
||||||
|
FieldType type = sf.getType();
|
||||||
|
if (fidx1 + 1 == fidx2) {
|
||||||
|
if (sf.multiValued()) {
|
||||||
|
startTagOpen(writer, "arr", fieldName);
|
||||||
|
writeField(writer, type, null, f1.stringValue()); //sf.write(this, null, f1);
|
||||||
|
writer.write("</arr>");
|
||||||
|
} else {
|
||||||
|
writeField(writer, type, f1.name(), f1.stringValue()); //sf.write(this, f1.name(), f1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
startTagOpen(writer, "arr", fieldName);
|
||||||
|
for (int i = fidx1; i < fidx2; i++) {
|
||||||
|
writeField(writer, type, null, fields.get(i).stringValue()); //sf.write(this, null, (Fieldable)this.tlst.get(i));
|
||||||
|
}
|
||||||
|
writer.write("</arr>");
|
||||||
|
writer.write(lb);
|
||||||
|
}
|
||||||
|
fidx1 = fidx2;
|
||||||
|
}
|
||||||
|
writer.write("</doc>");
|
||||||
|
writer.write(lb);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void writeField(final Writer writer, final FieldType type, final String name, final String value) throws IOException {
|
||||||
|
String typeName = type.getTypeName();
|
||||||
|
if (typeName.equals("text_general") || typeName.equals("string") || typeName.equals("text_en_splitting_tight")) {
|
||||||
|
writeTag(writer, "str", name, value, true);
|
||||||
|
} else if (typeName.equals("boolean")) {
|
||||||
|
writeTag(writer, "bool", name, "F".equals(value) ? "false" : "true", true);
|
||||||
|
} else if (typeName.equals("int")) {
|
||||||
|
writeTag(writer, "int", name, value, true);
|
||||||
|
} else if (typeName.equals("long")) {
|
||||||
|
writeTag(writer, "long", name, value, true);
|
||||||
|
} else if (typeName.equals("date")) {
|
||||||
|
writeTag(writer, "date", name, DateField.formatExternal(new Date(Long.parseLong(value))), true);
|
||||||
|
} else if (typeName.equals("float")) {
|
||||||
|
writeTag(writer, "float", name, value, true);
|
||||||
|
} else if (typeName.equals("double")) {
|
||||||
|
writeTag(writer, "double", name, value, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void writeTag(final Writer writer, final String tag, final String nameAttr, final String val, final boolean escape) throws IOException {
|
||||||
|
int contentLen = val.length();
|
||||||
|
if (contentLen == 0) {
|
||||||
|
startTagClose(writer, tag, nameAttr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
startTagOpen(writer, tag, nameAttr);
|
||||||
|
if (escape) {
|
||||||
|
XML.escapeCharData(val, writer);
|
||||||
|
} else {
|
||||||
|
writer.write(val, 0, contentLen);
|
||||||
|
}
|
||||||
|
writer.write("</"); writer.write(tag); writer.write('>'); writer.write(lb);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void startTagOpen(final Writer writer, final String tag, final String nameAttr) throws IOException {
|
||||||
|
writer.write('<'); writer.write(tag);
|
||||||
|
if (nameAttr != null) writeAttr(writer, "name", nameAttr);
|
||||||
|
writer.write('>'); writer.write(lb);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void startTagClose(final Writer writer, final String tag, final String nameAttr) throws IOException {
|
||||||
|
writer.write('<'); writer.write(tag);
|
||||||
|
if (nameAttr != null) writeAttr(writer, "name", nameAttr);
|
||||||
|
writer.write("/>"); writer.write(lb);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void writeAttr(final Writer writer, final String nameAttr, final String val) throws IOException {
|
||||||
|
writer.write(' '); writer.write(nameAttr); writer.write("=\""); XML.escapeAttributeValue(val, writer); writer.write('"');
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,301 @@
|
|||||||
|
/**
|
||||||
|
* OpensearchResponseWriter
|
||||||
|
* Copyright 2012 by Michael Peter Christen
|
||||||
|
* First released 06.08.2012 at http://yacy.net
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program in the file lgpl21.txt
|
||||||
|
* If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.yacy.cora.services.federated.solr;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Writer;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.apache.lucene.document.Document;
|
||||||
|
import org.apache.lucene.document.Fieldable;
|
||||||
|
import org.apache.solr.common.util.NamedList;
|
||||||
|
import org.apache.solr.common.util.SimpleOrderedMap;
|
||||||
|
import org.apache.solr.request.SolrQueryRequest;
|
||||||
|
import org.apache.solr.response.QueryResponseWriter;
|
||||||
|
import org.apache.solr.response.SolrQueryResponse;
|
||||||
|
import org.apache.solr.search.DocIterator;
|
||||||
|
import org.apache.solr.search.DocSlice;
|
||||||
|
import org.apache.solr.search.SolrIndexSearcher;
|
||||||
|
|
||||||
|
public class OpensearchResponseWriter implements QueryResponseWriter {
|
||||||
|
|
||||||
|
private static final char lb = '\n';
|
||||||
|
private static final char[] XML_START = (
|
||||||
|
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
|
||||||
|
"<?xml-stylesheet type='text/xsl' href='/yacysearch.xsl' version='1.0'?>\n" +
|
||||||
|
"<rss version=\"2.0\"\n" +
|
||||||
|
" xmlns:yacy=\"http://www.yacy.net/\"\n" +
|
||||||
|
" xmlns:opensearch=\"http://a9.com/-/spec/opensearch/1.1/\"\n" +
|
||||||
|
" xmlns:media=\"http://search.yahoo.com/mrss/\"\n" +
|
||||||
|
" xmlns:atom=\"http://www.w3.org/2005/Atom\"\n" +
|
||||||
|
" xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n" +
|
||||||
|
" xmlns:geo=\"http://www.w3.org/2003/01/geo/wgs84_pos#\"\n" +
|
||||||
|
">\n").toCharArray();
|
||||||
|
private static final char[] XML_STOP = "</rss>\n".toCharArray();
|
||||||
|
private static final Set<String> DEFAULT_FIELD_LIST = null;
|
||||||
|
|
||||||
|
private final String title;
|
||||||
|
|
||||||
|
private static class ResHead {
|
||||||
|
public int offset, rows, numFound;
|
||||||
|
//public int status, QTime;
|
||||||
|
//public String df, q, wt;
|
||||||
|
//public float maxScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OpensearchResponseWriter(String searchPageTitle) {
|
||||||
|
super();
|
||||||
|
this.title = searchPageTitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getContentType(final SolrQueryRequest request, final SolrQueryResponse response) {
|
||||||
|
return CONTENT_TYPE_XML_UTF8;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(@SuppressWarnings("rawtypes") NamedList n) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(final Writer writer, final SolrQueryRequest request, final SolrQueryResponse rsp) throws IOException {
|
||||||
|
writer.write(XML_START);
|
||||||
|
|
||||||
|
assert rsp.getValues().get("responseHeader") != null;
|
||||||
|
assert rsp.getValues().get("response") != null;
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
SimpleOrderedMap<Object> responseHeader = (SimpleOrderedMap<Object>) rsp.getResponseHeader();
|
||||||
|
DocSlice response = (DocSlice) rsp.getValues().get("response");
|
||||||
|
|
||||||
|
// parse response header
|
||||||
|
ResHead resHead = new ResHead();
|
||||||
|
NamedList<?> val0 = (NamedList<?>) responseHeader.get("params");
|
||||||
|
resHead.rows = Integer.parseInt((String) val0.get("rows"));
|
||||||
|
resHead.offset = response.offset(); // equal to 'start'
|
||||||
|
resHead.numFound = response.matches();
|
||||||
|
//resHead.df = (String) val0.get("df");
|
||||||
|
//resHead.q = (String) val0.get("q");
|
||||||
|
//resHead.wt = (String) val0.get("wt");
|
||||||
|
//resHead.status = (Integer) responseHeader.get("status");
|
||||||
|
//resHead.QTime = (Integer) responseHeader.get("QTime");
|
||||||
|
//resHead.maxScore = response.maxScore();
|
||||||
|
|
||||||
|
// write header
|
||||||
|
startTagOpen(writer, "channel");
|
||||||
|
solitaireTag(writer, "opensearch:totalResults", Integer.toString(resHead.numFound));
|
||||||
|
solitaireTag(writer, "opensearch:startIndex", Integer.toString(resHead.offset));
|
||||||
|
solitaireTag(writer, "opensearch:itemsPerPage", Integer.toString(resHead.rows));
|
||||||
|
solitaireTag(writer, "title", this.title);
|
||||||
|
//solitaireTag(writer, "description", "");
|
||||||
|
//solitaireTag(writer, "link", "");
|
||||||
|
//solitaireTag(writer, "image", "");
|
||||||
|
|
||||||
|
// parse body
|
||||||
|
final int responseCount = response.size();
|
||||||
|
SolrIndexSearcher searcher = request.getSearcher();
|
||||||
|
DocIterator iterator = response.iterator();
|
||||||
|
for (int i = 0; i < responseCount; i++) {
|
||||||
|
startTagOpen(writer, "item");
|
||||||
|
int id = iterator.nextDoc();
|
||||||
|
Document doc = searcher.doc(id, DEFAULT_FIELD_LIST);
|
||||||
|
List<Fieldable> fields = doc.getFields();
|
||||||
|
int fieldc = fields.size();
|
||||||
|
List<String> texts = new ArrayList<String>();
|
||||||
|
String description = "";
|
||||||
|
for (int j = 0; j < fieldc; j++) {
|
||||||
|
Fieldable f1 = fields.get(j);
|
||||||
|
String fieldName = f1.name();
|
||||||
|
if ("id".equals(fieldName)) {writer.write("<guid isPermaLink=\"false\">"); writer.write(f1.stringValue()); writer.write("</guid>"); writer.write(lb); continue;}
|
||||||
|
if ("sku".equals(fieldName)) {solitaireTag(writer, "link", f1.stringValue()); continue;}
|
||||||
|
if ("title".equals(fieldName)) {solitaireTag(writer, "title", f1.stringValue()); texts.add(f1.stringValue()); continue;}
|
||||||
|
if ("last_modified".equals(fieldName)) {solitaireTag(writer, "pubDate", f1.stringValue()); continue;}
|
||||||
|
if ("".equals(fieldName)) {solitaireTag(writer, "dc:publisher", f1.stringValue()); continue;}
|
||||||
|
if ("".equals(fieldName)) {solitaireTag(writer, "dc:creator", f1.stringValue()); continue;}
|
||||||
|
if ("description".equals(fieldName)) {description = f1.stringValue(); solitaireTag(writer, "dc:subject", description); texts.add(description); continue;}
|
||||||
|
if ("text_t".equals(fieldName)) {texts.add(f1.stringValue()); continue;}
|
||||||
|
if ("h1_txt".equals(fieldName) || "h2_txt".equals(fieldName) || "h3_txt".equals(fieldName) ||
|
||||||
|
"h4_txt".equals(fieldName) || "h5_txt".equals(fieldName) || "h6_txt".equals(fieldName)) {texts.add(f1.stringValue()); continue;}
|
||||||
|
}
|
||||||
|
// compute snippet from texts
|
||||||
|
solitaireTag(writer, "description", description);
|
||||||
|
closeTag(writer, "item");
|
||||||
|
}
|
||||||
|
|
||||||
|
closeTag(writer, "channel");
|
||||||
|
writer.write(XML_STOP);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void startTagOpen(final Writer writer, final String tag) throws IOException {
|
||||||
|
writer.write('<'); writer.write(tag); writer.write('>'); writer.write(lb);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void closeTag(final Writer writer, final String tag) throws IOException {
|
||||||
|
writer.write("</"); writer.write(tag); writer.write('>'); writer.write(lb);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void solitaireTag(final Writer writer, final String tagname, String value) throws IOException {
|
||||||
|
writer.write("<"); writer.write(tagname); writer.write('>');
|
||||||
|
writer.write(value);
|
||||||
|
writer.write("</"); writer.write(tagname); writer.write('>'); writer.write(lb);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
<!-- YaCy Search Engine; http://yacy.net -->
|
||||||
|
<channel>
|
||||||
|
<title>#[promoteSearchPageGreeting]#</title>
|
||||||
|
<description>Search for #[rss_query]#</description>
|
||||||
|
<link>#[searchBaseURL]#?query=#[rss_queryenc]#&resource=#[resource]#&contentdom=#[contentdom]#&verify=#[verify]#</link>
|
||||||
|
<image>
|
||||||
|
<url>#[rssYacyImageURL]#</url>
|
||||||
|
<title>Search for #[rss_query]#</title>
|
||||||
|
<link>#[searchBaseURL]#?query=#[rss_queryenc]#&resource=#[resource]#&contentdom=#[contentdom]#&verify=#[verify]#</link>
|
||||||
|
</image>
|
||||||
|
<opensearch:totalResults>#[num-results_totalcount]#</opensearch:totalResults>
|
||||||
|
<opensearch:startIndex>#[num-results_offset]#</opensearch:startIndex>
|
||||||
|
<opensearch:itemsPerPage>#[num-results_itemsPerPage]#</opensearch:itemsPerPage>
|
||||||
|
<atom:link rel=\"search\" href=\"http://#[thisaddress]#/opensearchdescription.xml\" type=\"application/opensearchdescription+xml\"/>
|
||||||
|
<opensearch:Query role=\"request\" searchTerms=\"#[rss_queryenc]#\" />
|
||||||
|
|
||||||
|
|
||||||
|
<!-- results -->
|
||||||
|
<item>
|
||||||
|
<title>#[title-xml]#</title>
|
||||||
|
<link>#[link]#</link>
|
||||||
|
<description>#[description-xml]#</description>
|
||||||
|
<pubDate>#[date822]#</pubDate>
|
||||||
|
<dc:publisher><![CDATA[#[publisher]#]]></dc:publisher>
|
||||||
|
<dc:creator><![CDATA[#[creator]#]]></dc:creator>
|
||||||
|
<dc:subject><![CDATA[#[subject]#]]></dc:subject>
|
||||||
|
<yacy:size>#[size]#</yacy:size>
|
||||||
|
<yacy:sizename>#[sizename]#</yacy:sizename>
|
||||||
|
<yacy:host>#[host]#</yacy:host>
|
||||||
|
<yacy:path>#[path]#</yacy:path>
|
||||||
|
<yacy:file>#[file]#</yacy:file>
|
||||||
|
<guid isPermaLink=\"false\">#[urlhash]#</guid>
|
||||||
|
#(loc)#::<geo:lat>#[lat]#</geo:lat><geo:long>#[lon]#</geo:long>#(/loc)#
|
||||||
|
</item>::
|
||||||
|
#(item)#::<item>
|
||||||
|
<title>#[name]#</title>
|
||||||
|
<link>#[source-xml]#</link>
|
||||||
|
<description></description>
|
||||||
|
<pubDate></pubDate>
|
||||||
|
<guid isPermaLink=\"false\">#[urlhash]#</guid>
|
||||||
|
<yacy:host>#[sourcedom]#</yacy:host>
|
||||||
|
<media:group>
|
||||||
|
<media:content
|
||||||
|
url=\"#[href]#\"
|
||||||
|
fileSize=\"#[fileSize]#\"
|
||||||
|
type=\"#[mimetype]#\"
|
||||||
|
medium=\"image\"
|
||||||
|
isDefault=\"true\"
|
||||||
|
expression=\"full\"
|
||||||
|
height=\"#[width]#\"
|
||||||
|
width=\"#[height]#\" />
|
||||||
|
<media:content
|
||||||
|
url=\"#[hrefCache]#\"
|
||||||
|
fileSize=\"#[fileSize]#\"
|
||||||
|
type=\"#[mimetype]#\"
|
||||||
|
medium=\"image\"
|
||||||
|
isDefault=\"false\"
|
||||||
|
expression=\"full\"
|
||||||
|
height=\"#[width]#\"
|
||||||
|
width=\"#[height]#\" />
|
||||||
|
<media:content
|
||||||
|
url=\"/ViewImage.png?maxwidth=96&maxheight=96&code=#[code]#\"
|
||||||
|
fileSize=\"#[fileSize]#\"
|
||||||
|
type=\"#[mimetype]#\"
|
||||||
|
medium=\"image\"
|
||||||
|
isDefault=\"false\"
|
||||||
|
expression=\"sample\"
|
||||||
|
height=\"96\"
|
||||||
|
width=\"96\" />
|
||||||
|
</media:group>
|
||||||
|
</item>
|
||||||
|
|
||||||
|
<!-- footer -->
|
||||||
|
<yacy:navigation>
|
||||||
|
|
||||||
|
#(nav-domains)#::
|
||||||
|
<yacy:facet name=\"domains\" displayname=\"Domains\" type=\"String\" min=\"0\" max=\"0\" mean=\"0\">
|
||||||
|
#{element}#
|
||||||
|
<yacy:element name=\"#[name]#\" count=\"#[count]#\" modifier=\"#[modifier]#\" />
|
||||||
|
#{/element}#
|
||||||
|
</yacy:facet>
|
||||||
|
#(/nav-domains)#
|
||||||
|
|
||||||
|
#(nav-namespace)#::
|
||||||
|
<yacy:facet name=\"namespace\" displayname=\"Namespace\" type=\"String\" min=\"0\" max=\"0\" mean=\"0\">
|
||||||
|
#{element}#
|
||||||
|
<yacy:element name=\"#[name]#\" count=\"#[count]#\" modifier=\"#[modifier]#\" />
|
||||||
|
#{/element}#
|
||||||
|
</yacy:facet>
|
||||||
|
#(/nav-namespace)#
|
||||||
|
|
||||||
|
#(nav-authors)#::
|
||||||
|
<yacy:facet name=\"authors\" displayname=\"Authors\" type=\"String\" min=\"0\" max=\"0\" mean=\"0\">
|
||||||
|
#{element}#
|
||||||
|
<yacy:element name=\"#[name]#\" count=\"#[count]#\" modifier=\"#[modifier]#\" />
|
||||||
|
#{/element}#
|
||||||
|
</yacy:facet>
|
||||||
|
#(/nav-authors)#
|
||||||
|
|
||||||
|
#(nav-filetype)#::
|
||||||
|
<yacy:facet name=\"filetypes\" displayname=\"Filetypes\" type=\"String\" min=\"0\" max=\"0\" mean=\"0\">
|
||||||
|
#{element}#
|
||||||
|
<yacy:element name=\"#[name]#\" count=\"#[count]#\" modifier=\"#[modifier]#\" />
|
||||||
|
#{/element}#
|
||||||
|
</yacy:facet>
|
||||||
|
#(/nav-filetype)#
|
||||||
|
|
||||||
|
#(nav-protocol)#::
|
||||||
|
<yacy:facet name=\"protocols\" displayname=\"Protocols\" type=\"String\" min=\"0\" max=\"0\" mean=\"0\">
|
||||||
|
#{element}#
|
||||||
|
<yacy:element name=\"#[name]#\" count=\"#[count]#\" modifier=\"#[modifier]#\" />
|
||||||
|
#{/element}#
|
||||||
|
</yacy:facet>
|
||||||
|
#(/nav-protocol)#
|
||||||
|
|
||||||
|
#(nav-topics)#::
|
||||||
|
<yacy:facet name=\"topics\" displayname=\"Topics\" type=\"String\" min=\"0\" max=\"0\" mean=\"0\">
|
||||||
|
#{element}#
|
||||||
|
<yacy:element name=\"#[name]#\" count=\"#[count]#\" modifier=\"#[modifier]#\" />
|
||||||
|
#{/element}#
|
||||||
|
</yacy:facet>
|
||||||
|
#(/nav-topics)#
|
||||||
|
|
||||||
|
#{nav-vocabulary}#
|
||||||
|
<yacy:facet name=\"#[navname]#\" displayname=\"#[navname]#\" type=\"String\" min=\"0\" max=\"0\" mean=\"0\">
|
||||||
|
#{element}#
|
||||||
|
<yacy:element name=\"#[name]#\" count=\"#[count]#\" modifier=\"#[modifier]#\" />
|
||||||
|
#{/element}#
|
||||||
|
</yacy:facet>
|
||||||
|
#{/nav-vocabulary}#
|
||||||
|
|
||||||
|
</yacy:navigation>
|
||||||
|
|
||||||
|
<opensearch:totalResults>#[num-results_totalcount]#</opensearch:totalResults>
|
||||||
|
</channel>
|
||||||
|
*/
|
Loading…
Reference in new issue