mirror of https://github.com/apache/lucene.git
GData html render preview: LUCENE-660
git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@433051 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
9763d03f48
commit
8c0d242750
|
@ -58,6 +58,7 @@ public class GDataRequest {
|
|||
private static final String RESPONSE_FORMAT_PARAMETER = "alt";
|
||||
|
||||
private static final String RESPONSE_FORMAT_PARAMETER_RSS = "rss";
|
||||
private static final String RESPONSE_FORMAT_PARAMETER_HTML = "html";
|
||||
|
||||
private static final int DEFAULT_ITEMS_PER_PAGE = 25;
|
||||
|
||||
|
@ -276,6 +277,8 @@ public class GDataRequest {
|
|||
return;
|
||||
if (formatParameter.equalsIgnoreCase(RESPONSE_FORMAT_PARAMETER_RSS))
|
||||
this.responseFormat = OutputFormat.RSS;
|
||||
if (formatParameter.equalsIgnoreCase(RESPONSE_FORMAT_PARAMETER_HTML))
|
||||
this.responseFormat = OutputFormat.HTML;
|
||||
|
||||
}
|
||||
|
||||
|
@ -439,7 +442,11 @@ public class GDataRequest {
|
|||
/**
|
||||
* Output format RSS
|
||||
*/
|
||||
RSS
|
||||
RSS,
|
||||
/**
|
||||
* Output format html if user defined xsl style sheet is present
|
||||
*/
|
||||
HTML
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -17,14 +17,23 @@
|
|||
package org.apache.lucene.gdata.server;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
import java.util.Date;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.transform.Templates;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
import javax.xml.transform.stream.StreamSource;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.lucene.gdata.server.GDataRequest.OutputFormat;
|
||||
import org.apache.lucene.gdata.server.registry.ProvidedService;
|
||||
import org.apache.lucene.gdata.utils.DateFormater;
|
||||
|
||||
import com.google.gdata.data.BaseEntry;
|
||||
|
@ -104,7 +113,7 @@ public class GDataResponse {
|
|||
public static final int UNAUTHORIZED = HttpServletResponse.SC_UNAUTHORIZED;
|
||||
|
||||
|
||||
private static final Log LOG = LogFactory.getLog(GDataResponse.class);
|
||||
static final Log LOG = LogFactory.getLog(GDataResponse.class);
|
||||
private int error;
|
||||
|
||||
private boolean isError = false;
|
||||
|
@ -119,11 +128,6 @@ public class GDataResponse {
|
|||
|
||||
protected static final String XMLMIME_RSS = "text/xml";
|
||||
|
||||
private static final String DEFAUL_NAMESPACE_URI = "http://www.w3.org/2005/Atom";
|
||||
|
||||
private static final Namespace DEFAULT_NAMESPACE = new Namespace("",
|
||||
DEFAUL_NAMESPACE_URI);
|
||||
|
||||
private static final String HEADER_LASTMODIFIED = "Last-Modified";
|
||||
|
||||
/**
|
||||
|
@ -188,33 +192,26 @@ public class GDataResponse {
|
|||
*
|
||||
* @param feed -
|
||||
* the feed to respond to the client
|
||||
* @param profile -
|
||||
* the extension profile for the feed to write
|
||||
* @param service - the service to render the feed
|
||||
*
|
||||
* @throws IOException -
|
||||
* if an I/O exception occurs, often caused by an already
|
||||
* closed Writer or OutputStream
|
||||
*
|
||||
*/
|
||||
public void sendResponse(BaseFeed feed, ExtensionProfile profile)
|
||||
public void sendResponse(final BaseFeed feed, final ProvidedService service)
|
||||
throws IOException {
|
||||
if (feed == null)
|
||||
throw new IllegalArgumentException("feed must not be null");
|
||||
if (profile == null)
|
||||
if (service == null)
|
||||
throw new IllegalArgumentException(
|
||||
"extension profile must not be null");
|
||||
"provided service must not be null");
|
||||
DateTime time = feed.getUpdated();
|
||||
if (time != null)
|
||||
setLastModifiedHeader(time.getValue());
|
||||
XmlWriter writer = createWriter();
|
||||
FormatWriter writer = FormatWriter.getFormatWriter(this,service);
|
||||
writer.generateOutputFormat(feed,this.response);
|
||||
|
||||
if (this.outputFormat.equals(OutputFormat.ATOM)) {
|
||||
this.response.setContentType(XMLMIME_ATOM);
|
||||
feed.generateAtom(writer, profile);
|
||||
} else {
|
||||
this.response.setContentType(XMLMIME_RSS);
|
||||
feed.generateRss(writer, profile);
|
||||
}
|
||||
writer.close();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -226,38 +223,27 @@ public class GDataResponse {
|
|||
*
|
||||
* @param entry -
|
||||
* the modified / created entry to send
|
||||
* @param profile -
|
||||
* the entries extension profile
|
||||
* @param service - the service to render the feed
|
||||
* @throws IOException -
|
||||
* if an I/O exception occurs, often caused by an already
|
||||
* closed Writer or OutputStream
|
||||
*/
|
||||
public void sendResponse(BaseEntry entry, ExtensionProfile profile)
|
||||
public void sendResponse(BaseEntry entry, ProvidedService service)
|
||||
throws IOException {
|
||||
if (entry == null)
|
||||
throw new IllegalArgumentException("entry must not be null");
|
||||
if (profile == null)
|
||||
if (service == null)
|
||||
throw new IllegalArgumentException(
|
||||
"extension profile must not be null");
|
||||
"service must not be null");
|
||||
DateTime time = entry.getUpdated();
|
||||
if (time != null)
|
||||
setLastModifiedHeader(time.getValue());
|
||||
XmlWriter writer = createWriter();
|
||||
if (this.outputFormat.equals(OutputFormat.ATOM))
|
||||
entry.generateAtom(writer, profile);
|
||||
else
|
||||
entry.generateRss(writer, profile);
|
||||
writer.close();
|
||||
FormatWriter writer = FormatWriter.getFormatWriter(this,service);
|
||||
writer.generateOutputFormat(entry,this.response);
|
||||
|
||||
|
||||
}
|
||||
|
||||
private XmlWriter createWriter() throws IOException {
|
||||
XmlWriter writer = new XmlWriter(getWriter(), this.encoding);
|
||||
// set the default namespace to Atom if Atom is the response format
|
||||
if (this.outputFormat.equals(OutputFormat.ATOM))
|
||||
writer.setDefaultNamespace(DEFAULT_NAMESPACE);
|
||||
return writer;
|
||||
}
|
||||
|
||||
/**
|
||||
* This encoding will be used to encode the xml representation of feed or
|
||||
|
@ -326,4 +312,138 @@ public class GDataResponse {
|
|||
this.response.setStatus(status);
|
||||
}
|
||||
|
||||
private static abstract class FormatWriter{
|
||||
|
||||
static FormatWriter getFormatWriter(final GDataResponse response, final ProvidedService service ){
|
||||
OutputFormat format = response.getOutputFormat();
|
||||
if(format == OutputFormat.HTML){
|
||||
return new HTMLFormatWriter(service);
|
||||
}
|
||||
return new SyndicateFormatWriter(service,format,response.getEncoding());
|
||||
}
|
||||
|
||||
abstract void generateOutputFormat(final BaseFeed feed, final HttpServletResponse response) throws IOException;
|
||||
abstract void generateOutputFormat(final BaseEntry entry, final HttpServletResponse response) throws IOException;
|
||||
|
||||
private static class HTMLFormatWriter extends FormatWriter{
|
||||
private static final String CONTENT_TYPE = "text/html";
|
||||
private final ProvidedService service;
|
||||
|
||||
HTMLFormatWriter(final ProvidedService service){
|
||||
this.service = service;
|
||||
}
|
||||
@Override
|
||||
void generateOutputFormat(BaseFeed feed, final HttpServletResponse response) throws IOException {
|
||||
Templates template = this.service.getTransformTemplate();
|
||||
response.setContentType(CONTENT_TYPE);
|
||||
if(template == null){
|
||||
sendNotAvailable(response);
|
||||
return;
|
||||
}
|
||||
StringWriter writer = new StringWriter();
|
||||
XmlWriter xmlWriter = new XmlWriter(writer);
|
||||
feed.generateAtom(xmlWriter,this.service.getExtensionProfile());
|
||||
try {
|
||||
writeHtml(template,response.getWriter(),writer);
|
||||
} catch (TransformerException e) {
|
||||
LOG.error("Can not transform feed for service "+this.service.getName(),e);
|
||||
sendNotAvailable(response);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void generateOutputFormat(BaseEntry entry, final HttpServletResponse response) throws IOException{
|
||||
Templates template = this.service.getTransformTemplate();
|
||||
response.setContentType(CONTENT_TYPE);
|
||||
if(template == null){
|
||||
sendNotAvailable(response);
|
||||
return;
|
||||
}
|
||||
StringWriter writer = new StringWriter();
|
||||
XmlWriter xmlWriter = new XmlWriter(writer);
|
||||
entry.generateAtom(xmlWriter,this.service.getExtensionProfile());
|
||||
try {
|
||||
writeHtml(template,response.getWriter(),writer);
|
||||
} catch (TransformerException e) {
|
||||
LOG.error("Can not transform feed for service "+this.service.getName(),e);
|
||||
sendNotAvailable(response);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void writeHtml(final Templates template, final Writer writer, final StringWriter source ) throws TransformerException{
|
||||
Transformer transformer = template.newTransformer();
|
||||
Source tranformSource = new StreamSource(new StringReader(source.toString()));
|
||||
transformer.transform(tranformSource,new StreamResult(writer));
|
||||
}
|
||||
|
||||
private void sendNotAvailable(final HttpServletResponse response) throws IOException{
|
||||
response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, "No transformation stylesheet available");
|
||||
}
|
||||
|
||||
}
|
||||
private static class SyndicateFormatWriter extends FormatWriter{
|
||||
private static final String DEFAUL_NAMESPACE_URI = "http://www.w3.org/2005/Atom";
|
||||
|
||||
private static final Namespace DEFAULT_NAMESPACE = new Namespace("",
|
||||
DEFAUL_NAMESPACE_URI);
|
||||
private final ProvidedService service;
|
||||
private final String encoding;
|
||||
private final OutputFormat format;
|
||||
|
||||
SyndicateFormatWriter(final ProvidedService service,final OutputFormat format, String encoding){
|
||||
this.service = service;
|
||||
this.format = format;
|
||||
this.encoding = encoding;
|
||||
|
||||
}
|
||||
@Override
|
||||
void generateOutputFormat(final BaseFeed feed, final HttpServletResponse response) throws IOException {
|
||||
XmlWriter writer = null;
|
||||
try{
|
||||
writer = createWriter(response.getWriter());
|
||||
if (this.format == OutputFormat.ATOM) {
|
||||
response.setContentType(XMLMIME_ATOM);
|
||||
feed.generateAtom(writer, this.service.getExtensionProfile());
|
||||
} else {
|
||||
response.setContentType(XMLMIME_RSS);
|
||||
feed.generateRss(writer, this.service.getExtensionProfile());
|
||||
}
|
||||
}finally{
|
||||
if(writer != null)
|
||||
writer.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void generateOutputFormat(final BaseEntry entry, final HttpServletResponse response) throws IOException {
|
||||
XmlWriter writer = null;
|
||||
try{
|
||||
writer = createWriter(response.getWriter());
|
||||
if (this.format == OutputFormat.ATOM) {
|
||||
response.setContentType(XMLMIME_ATOM);
|
||||
entry.generateAtom(writer, this.service.getExtensionProfile());
|
||||
} else {
|
||||
response.setContentType(XMLMIME_RSS);
|
||||
entry.generateRss(writer, this.service.getExtensionProfile());
|
||||
}
|
||||
}finally{
|
||||
if(writer != null)
|
||||
writer.close();
|
||||
}
|
||||
}
|
||||
private XmlWriter createWriter(final Writer target) throws IOException {
|
||||
XmlWriter writer = new XmlWriter(target, this.encoding);
|
||||
// set the default namespace to Atom if Atom is the response format
|
||||
if (this.format == OutputFormat.ATOM)
|
||||
writer.setDefaultNamespace(DEFAULT_NAMESPACE);
|
||||
return writer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
*/
|
||||
package org.apache.lucene.gdata.server.registry;
|
||||
|
||||
import javax.xml.transform.Templates;
|
||||
|
||||
import org.apache.lucene.gdata.search.config.IndexSchema;
|
||||
|
||||
import com.google.gdata.data.ExtensionProfile;
|
||||
|
@ -55,4 +57,9 @@ public interface ProvidedService {
|
|||
* @return the index schema configuration for this service
|
||||
*/
|
||||
public abstract IndexSchema getIndexSchema();
|
||||
/**
|
||||
* @return the compiled xslt stylesheet to transform the feed / entry for preview
|
||||
*/
|
||||
public abstract Templates getTransformTemplate();
|
||||
|
||||
}
|
|
@ -17,6 +17,11 @@ package org.apache.lucene.gdata.server.registry;
|
|||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
import javax.xml.transform.Templates;
|
||||
import javax.xml.transform.TransformerConfigurationException;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.stream.StreamSource;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.lucene.gdata.search.config.IndexSchema;
|
||||
|
@ -26,9 +31,7 @@ import org.apache.lucene.gdata.utils.SimpleObjectPool;
|
|||
|
||||
import com.google.gdata.data.BaseEntry;
|
||||
import com.google.gdata.data.BaseFeed;
|
||||
import com.google.gdata.data.Entry;
|
||||
import com.google.gdata.data.ExtensionProfile;
|
||||
import com.google.gdata.data.Feed;
|
||||
|
||||
/**
|
||||
* Standard implementation of
|
||||
|
@ -79,6 +82,9 @@ public class ProvidedServiceConfig implements ProvidedService, ScopeVisitor {
|
|||
|
||||
private int poolSize = DEFAULT_POOL_SIZE;
|
||||
|
||||
private Templates transformerTemplate;
|
||||
|
||||
|
||||
/**
|
||||
* @return Returns the poolSize.
|
||||
*/
|
||||
|
@ -326,4 +332,33 @@ public class ProvidedServiceConfig implements ProvidedService, ScopeVisitor {
|
|||
this.indexSchema.setName(this.serviceName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.server.registry.ProvidedService#getTransformTemplate()
|
||||
*/
|
||||
public Templates getTransformTemplate() {
|
||||
|
||||
return this.transformerTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets and creates the preview transformer xslt template to provide a html formate for feeds and entries.
|
||||
* The given file name must be available in the classpath.
|
||||
* @param filename - the name of the file in the classpath
|
||||
*/
|
||||
public void setXsltStylesheet(String filename){
|
||||
if(filename == null || filename.length() == 0){
|
||||
LOG.info("No preview stylesheet configured for service "+this.serviceName);
|
||||
return;
|
||||
}
|
||||
|
||||
TransformerFactory factory = TransformerFactory.newInstance();
|
||||
|
||||
try {
|
||||
this.transformerTemplate = factory.newTemplates(new StreamSource(ProvidedServiceConfig.class.getResourceAsStream(filename.startsWith("/")?filename:"/"+filename)));
|
||||
} catch (TransformerConfigurationException e) {
|
||||
throw new RuntimeException("Can not compile xslt stylesheet path: "+filename,e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -77,6 +77,7 @@ class RegistryBuilder {
|
|||
digester.addBeanPropertySetter("gdata/service/entry-class", "entryType");
|
||||
digester.addBeanPropertySetter("gdata/service/extension-profile",
|
||||
"extensionProfileClass");
|
||||
digester.addBeanPropertySetter("gdata/service/previewStyleSheet","xsltStylesheet");
|
||||
addIndexRule(digester);
|
||||
/*
|
||||
* load components and configurations
|
||||
|
|
|
@ -90,12 +90,12 @@ public class DefaultGetHandler extends AbstractGdataRequestHandler {
|
|||
this.feedResponse);
|
||||
|
||||
this.feedResponse.sendResponse(feed, this.feedRequest
|
||||
.getConfigurator().getExtensionProfile());
|
||||
.getConfigurator());
|
||||
} else {
|
||||
BaseEntry entry = this.service.getSingleEntry(this.feedRequest,
|
||||
this.feedResponse);
|
||||
this.feedResponse.sendResponse(entry, this.feedRequest
|
||||
.getConfigurator().getExtensionProfile());
|
||||
.getConfigurator());
|
||||
}
|
||||
|
||||
} catch (ServiceException e) {
|
||||
|
|
|
@ -74,7 +74,7 @@ public class DefaultInsertHandler extends AbstractGdataRequestHandler {
|
|||
BaseEntry entry = this.service.createEntry(this.feedRequest,this.feedResponse);
|
||||
setFeedResponseFormat();
|
||||
setFeedResponseStatus(GDataResponse.CREATED);
|
||||
this.feedResponse.sendResponse(entry, this.feedRequest.getConfigurator().getExtensionProfile());
|
||||
this.feedResponse.sendResponse(entry, this.feedRequest.getConfigurator());
|
||||
|
||||
}catch (ServiceException e) {
|
||||
LOG.error("Could not process GetFeed request - "+e.getMessage(),e);
|
||||
|
|
|
@ -75,7 +75,7 @@ public class DefaultUpdateHandler extends AbstractGdataRequestHandler {
|
|||
BaseEntry entry = this.service.updateEntry(this.feedRequest,
|
||||
this.feedResponse);
|
||||
setFeedResponseFormat();
|
||||
this.feedResponse.sendResponse(entry, this.feedRequest.getConfigurator().getExtensionProfile());
|
||||
this.feedResponse.sendResponse(entry, this.feedRequest.getConfigurator());
|
||||
|
||||
}
|
||||
catch (ServiceException e) {
|
||||
|
|
|
@ -24,6 +24,7 @@ import javax.servlet.http.HttpServletResponse;
|
|||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.lucene.gdata.server.GDataRequest.OutputFormat;
|
||||
import org.apache.lucene.gdata.utils.ProvidedServiceStub;
|
||||
import org.easymock.MockControl;
|
||||
|
||||
import com.google.gdata.data.Entry;
|
||||
|
@ -69,7 +70,7 @@ public class TestGDataResponse extends TestCase {
|
|||
public void testSendResponseBaseFeedExtensionProfile() throws IOException {
|
||||
try{
|
||||
Feed f = null;
|
||||
this.response.sendResponse(f,new ExtensionProfile());
|
||||
this.response.sendResponse(f, new ProvidedServiceStub());
|
||||
fail("Exception expected");
|
||||
}catch (IllegalArgumentException e) {
|
||||
//
|
||||
|
@ -90,7 +91,7 @@ public class TestGDataResponse extends TestCase {
|
|||
this.response.setOutputFormat(OutputFormat.ATOM);
|
||||
this.control.replay();
|
||||
|
||||
this.response.sendResponse(createFeed(),new ExtensionProfile());
|
||||
this.response.sendResponse(createFeed(), new ProvidedServiceStub());
|
||||
assertEquals("Simple XML representation",stringWriter.toString(),generatedFeedAtom);
|
||||
this.control.reset();
|
||||
|
||||
|
@ -102,8 +103,7 @@ public class TestGDataResponse extends TestCase {
|
|||
this.httpResponse.setContentType(GDataResponse.XMLMIME_RSS);
|
||||
this.control.replay();
|
||||
|
||||
this.response.sendResponse(createFeed(),new ExtensionProfile
|
||||
());
|
||||
this.response.sendResponse(createFeed(), new ProvidedServiceStub());
|
||||
assertEquals("Simple XML representation",stringWriter.toString(),generatedFeedRSS);
|
||||
|
||||
|
||||
|
@ -117,7 +117,7 @@ public class TestGDataResponse extends TestCase {
|
|||
public void testSendResponseBaseEntryExtensionProfile() throws IOException {
|
||||
try{
|
||||
Entry e = null;
|
||||
this.response.sendResponse(e,new ExtensionProfile());
|
||||
this.response.sendResponse(e, new ProvidedServiceStub());
|
||||
fail("Exception expected");
|
||||
}catch (IllegalArgumentException e) {
|
||||
//
|
||||
|
@ -134,11 +134,11 @@ public class TestGDataResponse extends TestCase {
|
|||
PrintWriter writer = new PrintWriter(stringWriter);
|
||||
|
||||
this.control.expectAndReturn(this.httpResponse.getWriter(),writer);
|
||||
this.httpResponse.setContentType(GDataResponse.XMLMIME_ATOM);
|
||||
this.response.setOutputFormat(OutputFormat.ATOM);
|
||||
this.control.replay();
|
||||
|
||||
this.response.sendResponse(createEntry(),new ExtensionProfile
|
||||
());
|
||||
this.response.sendResponse(createEntry(), new ProvidedServiceStub());
|
||||
assertEquals("Simple XML representation ATOM",stringWriter.toString(),generatedEntryAtom);
|
||||
|
||||
// test rss output
|
||||
|
@ -147,11 +147,11 @@ public class TestGDataResponse extends TestCase {
|
|||
writer = new PrintWriter(stringWriter);
|
||||
|
||||
this.control.expectAndReturn(this.httpResponse.getWriter(),writer);
|
||||
this.httpResponse.setContentType(GDataResponse.XMLMIME_RSS);
|
||||
this.response.setOutputFormat(OutputFormat.RSS);
|
||||
this.control.replay();
|
||||
|
||||
this.response.sendResponse(createEntry(),new ExtensionProfile
|
||||
());
|
||||
this.response.sendResponse(createEntry(), new ProvidedServiceStub());
|
||||
|
||||
assertEquals("Simple XML representation RSS",stringWriter.toString(),generatedEntryRSS);
|
||||
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
*/
|
||||
package org.apache.lucene.gdata.utils;
|
||||
|
||||
import javax.xml.transform.Templates;
|
||||
|
||||
import org.apache.lucene.gdata.search.config.IndexSchema;
|
||||
import org.apache.lucene.gdata.server.registry.ProvidedService;
|
||||
|
||||
|
@ -63,4 +65,11 @@ public class ProvidedServiceStub implements ProvidedService {
|
|||
return this.indexSchema;
|
||||
}
|
||||
|
||||
public Templates getTransformTemplate() {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
<extension-profile>
|
||||
com.google.gdata.data.ExtensionProfile
|
||||
</extension-profile>
|
||||
<previewStyleSheet>transform.xslt</previewStyleSheet>
|
||||
<index-schema defaultSearchField="content">
|
||||
<index useTimedIndexer="true" indexerIdleTime="120" optimizeAfterCommit="5" commitAfterDocuments="10">
|
||||
<defaultAnalyzer>
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
<xs:element name="feed-class" type="xs:string" />
|
||||
<xs:element name="entry-class" type="xs:string" />
|
||||
<xs:element name="extension-profile" type="xs:string" />
|
||||
<xs:element name="previewStyleSheet" type="xs:string" />
|
||||
<xs:element name="class" type="xs:string" />
|
||||
<xs:annotation>
|
||||
<xs:documentation xml:lang="en">
|
||||
|
@ -27,6 +28,8 @@
|
|||
minOccurs="1" />
|
||||
<xs:element ref="extension-profile" maxOccurs="1"
|
||||
minOccurs="1" />
|
||||
<xs:element ref="previewStyleSheet" maxOccurs="1"
|
||||
minOccurs="0" />
|
||||
<xs:element ref="index-schema" maxOccurs="1"
|
||||
minOccurs="1" />
|
||||
</xs:sequence>
|
||||
|
|
Loading…
Reference in New Issue