Hai all,

I have a problem with resolving the relative path of a entity file within a xsl file.

I am using docbook for in my web application

In the Docbook the file named docbook.xsl which includes other xsl files

Among two such included xsl file(autoidx.xsl and glossary.xsl) in the a .ent file in its header as follows

<!DOCTYPE xsl:stylesheet [
<!ENTITY % common.entities *SYSTEM "../common/entities.ent"*>
%common.entities;
]>

Here comes the relative path problem.
I am getting the error

java.lang.Exception: Transformation error:
yanelrepo:/docbook-xsl-1.73.2/html/autoidx.xsl:Line=4;Column=18: exception:Had IO Exception with stylesheet file: autoidx.xsl
root-cause:null
line: logSourceLine unavailable due to: unknown protocol: yanelrepo


All xsl includes are resolved by two java class file written by me
named BasicXMLResource.java and SourceResolver.java

The BasicXMLResource is called from servlet.The getXMLView() is processing the xsl files and call the resolve() method in SourceResolver to resolve the relative path.

////////////////////////////getXSLView//////////////////////////////////////////////////////////////////////////////////////////
public View getXMLView(String viewId, InputStream xmlInputStream) throws Exception {
       View view = new View();
       if (viewId == null) {
           viewId = DEFAULT_VIEW_ID;
       }
ConfigurableViewDescriptor viewDescriptor = (ConfigurableViewDescriptor)getViewDescriptor(viewId);
       String mimeType = getMimeType(viewId);
       view.setMimeType(mimeType);

       StringWriter errorWriter = new StringWriter();
       try {
           if (viewId != null && viewId.equals(SOURCE_VIEW_ID)) {
               view.setInputStream(xmlInputStream);
               return view;
           }

           // create reader:
           XMLReader xmlReader = XMLReaderFactory.createXMLReader();
           CatalogResolver catalogResolver = new CatalogResolver();
//SourceEntityResolver sourceEntityResolver = new SourceEntityResolver();
           xmlReader.setEntityResolver(catalogResolver);
xmlReader.setFeature("http://xml.org/sax/features/namespace-prefixes";, true);

           SourceResolver uriResolver = new SourceResolver(this);
ListingErrorHandler errorListener = new ListingErrorHandler(new PrintWriter(errorWriter));

           // create xslt transformer:
SAXTransformerFactory tf = (SAXTransformerFactory)TransformerFactory.newInstance();
           tf.setURIResolver(uriResolver);
           tf.setErrorListener(errorListener);

           String[] xsltPaths = viewDescriptor.getXSLTPaths();
           if (xsltPaths == null || xsltPaths.length == 0) {
               xsltPaths = getXSLTPath(getPath());
           }
Repository repo = getRealm().getRepository(); TransformerHandler[] xsltHandlers = new TransformerHandler[xsltPaths.length];
           for (int i = 0; i < xsltPaths.length; i++) {
               // TODO: Use resolver
               if (xsltPaths[i].startsWith("file:")) {
                   log.warn("Scheme: file (" + xsltPaths[i] + ")");
xsltHandlers[i] = tf.newTransformerHandler(new StreamSource(new java.io.FileInputStream(xsltPaths[i].substring(5))));
               } else if(xsltPaths[i].startsWith("rthtdocs:")) {
                   log.warn("Scheme: rthtdocs (" + xsltPaths[i] + ")");
xsltHandlers[i] = tf.newTransformerHandler(new org.wyona.yanel.core.source.RTHtdocsResolver(this).resolve(xsltPaths[i], null));
               } else {
                   if (xsltPaths[i].indexOf(":/") > 0) {
log.error("No such protocol implemented: " + xsltPaths[i].substring(0, xsltPaths[i].indexOf(":/")));
                   } else {
                       if (log.isDebugEnabled()) {
log.debug("Default Content repository will be used!");
                       }
                   }
xsltHandlers[i] = tf.newTransformerHandler(new StreamSource(repo.getNode(xsltPaths[i]).getInputStream(), "yanelrepo:" + xsltPaths[i]));
               }
xsltHandlers[i].getTransformer().setURIResolver(uriResolver); xsltHandlers[i].getTransformer().setErrorListener(errorListener);
               passTransformerParameters(xsltHandlers[i].getTransformer());
           }

           // create i18n transformer:
I18nTransformer3 i18nTransformer = new I18nTransformer3(getI18NCatalogueNames(), getRequestedLanguage(), getRealm().getDefaultLanguage(), uriResolver);
           i18nTransformer.setEntityResolver(catalogResolver);

           // create xinclude transformer:
XIncludeTransformer xIncludeTransformer = new XIncludeTransformer();
           xIncludeTransformer.setResolver(uriResolver);

           // create serializer:
           Serializer serializer = createSerializer(viewDescriptor);

           ByteArrayOutputStream baos = new ByteArrayOutputStream();

           // chain everything together (create a pipeline):
           if (xsltHandlers.length > 0) {
               xmlReader.setContentHandler(xsltHandlers[0]);
               for (int i=0; i<xsltHandlers.length-1; i++) {
xsltHandlers[i].setResult(new SAXResult(xsltHandlers[i+1]));
               }
xsltHandlers[xsltHandlers.length-1].setResult(new SAXResult(xIncludeTransformer));
           } else {
xmlReader.setContentHandler(new SAXResult(xIncludeTransformer).getHandler());
           }
           xIncludeTransformer.setResult(new SAXResult(i18nTransformer));
i18nTransformer.setResult(new SAXResult(serializer.asContentHandler()));
           serializer.setOutputStream(baos);
           System.out.println("No error before parse");
           // execute pipeline:
           xmlReader.parse(new InputSource(xmlInputStream));
           System.out.println("No error after parse");

           // write result into view:
view.setInputStream(new ByteArrayInputStream(baos.toByteArray()));
           return view;
       } catch(Exception e) {
           log.error(e + " (" + getPath() + ", " + getRealm() + ")", e);
           String errorMsg;
           String transformationError = errorWriter.toString();
           if (transformationError != null) {
               errorMsg = "Transformation error:\n" + transformationError;
               log.error(errorMsg);
           } else {
               errorMsg = e.getMessage();
           }
           throw new Exception(errorMsg);
       }

   }
////////////////////////////////////////////////////Inside SourceResolver class///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public InputSource resolveEntity(String href, String base) {
       System.out.println("Entered");
       InputSource result;
       result = super.resolveEntity(href, base);
       result.setSystemId(base);
       return result;
} /**
    *
    */
   public Source resolve(String uri, String base) throws SourceException {
       if (log.isDebugEnabled()) {
           log.debug("URI to be resolved: " + uri);
           log.debug("Base: "+ base);
} // NOTE: One cannot use ":/" in order to find the protocol/scheme, because one can also specifiy the realm id and repository id, for example: yanelrepo:REALM_ID:REPO_ID:/foo/bar.gif
       int colonIndex = uri.indexOf(":");
       //int colonIndex = uri.indexOf(":/");
       String uriScheme = "";
if (colonIndex <= 0) {//Check for scheme in URI, if true, then URI has no scheme
           //log.error("DEBUG: URI has no scheme: " + uri);
           if (base != null) {
               int colBaseIndex = base.indexOf(":");
               //int colBaseIndex = base.indexOf(":/");
               if(colBaseIndex <=0 ){//Check for scheme in Base
throw new SourceException("invalid url syntax (missing scheme): " + uri);//no scheme found in uri and base
               }else{//base contains scheme. Use base scheme for uri scheme
                   uriScheme = base.substring(0, colBaseIndex);
uri = PathUtil.concat(base,uri); //log.error("DEBUG: Use scheme of base: " + uriScheme + ", " + uri);
               }
           } else {
log.error("Neither scheme for URI nor base specified for URI: " + uri); throw new SourceException("invalid url syntax (missing scheme): " + uri);//no scheme found in uri and base
           }
       } else {//uri contains scheme
           uriScheme = uri.substring(0, colonIndex);
           //log.error("DEBUG: URI has scheme: " + uriScheme + ", " + uri);
       }

       URIResolver resolver = getResolver(uriScheme);
       if (resolver != null) {
           try {
               // TODO: What shall be used as base?!
               Source s = resolver.resolve(uri, base);
               s.setSystemId(uri);
               return s;
           } catch (TransformerException e) {
               throw new SourceException(e.getMessage(), e);
           }
       } else {
throw new SourceException("No resolver could be loaded for scheme: " + uriScheme);
       }
   }

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

please help me



Best Regards
Navas

Reply via email to