2010-09-06 29 views
8

He estado tratando de usar XSL con Google Chrome, pero sin éxito.
He leído que Chrome tiene algunos errores con XSLT, y uno de ellos es que no es compatible con xsl: include. El error se puede verificar aquí: http://code.google.com/p/chromium/issues/detail?id=8441.
Después de algunas investigaciones encontré una nueva versión del plugin transform por Daer System, y hace que xsl: include funcione en Chrome.xsl: incluir y xsl: param en Google Chrome, con el complemento de transformación jQuery

jQuery Transform módulo se pueden encontrar a partir http://plugins.jquery.com/project/Transform

Ahora mi problema es:
utilizo un defecto incluir en algunas plantillas XSL, y esto incluye utiliza un parámetro que se pasa al nivel superior una.

Así que es como si tuviera la plantilla top.xsl que declara un [xsl: param name = "parámetro" /], y utilizo este parámetro con el included.xsl, que es llamado por el primero uno con [xsl: include href = "included.xsl"]. Esto funciona tanto en Firefox como en Internet Explorer, pero no en Chrome. Vi una pregunta aquí en stackoverflow donde un tipo vuelve a escribir la función de corrección de webkit desde el complemento, pero no funciona con xsl: param de esta manera.

¿Alguien sabe alguna forma de usar [xsl: param] como este en Google Chrome?

+0

Parece que esto es así solo cuando se ejecuta la transformación a través de javascript. Como puede ver, mi sitio impulsado por XML/XSLT funciona: www.aranedabienesraices.com.ar –

+0

Hola Alejandro, sí, esto es haciendo transformaciones de javascript. Necesito hacer esto a través de javascript. –

+0

user357812: por favor explique: ¿cómo es ese enlace relevante para esta pregunta? – jsalonen

Respuesta

1

Su problema aquí es que Google Chrome (= cromo) no admite xsl:include

La falta de esta característica se observa bien en el proyecto Chromium, como se plantea en "Issue 8441: XSLTProcessor in JS does not permit xsl:include for http". Parece que el problema está causado por algún problema arquitectónico en WebKit (el motor de renderizado utilizado en Chrome). Dado que este problema se origina en WebKit, el error se marca como WontFix: la corrección se proporcionará (con suerte) en el futuro a medida que se resuelva el problema original en el WebKit.

veo tres posibles alternativas de cómo este problema podría resolverse para usted:

  1. Esperar hasta que WebKit/Chrome consigue un parche que corrige este problema (potencialmente tarda mucho tiempo ...)
  2. Crear/encontrar un truco que funciona en torno a este problema, por ejemplo, mediante la emulación de alguna manera xsl:include para Chrome/Webkit (potencialmente requiere mucho trabajo/desarrollo de un hack)
  3. tratar de encontrar una manera de escribir el software i na manera que no se necesita esta función específica XSL (o bien ejecutar la transformación XSL en el lado del servidor)

Mi recomendación: evitar el uso de XSL: include con xsl: param en el lado del cliente a menos que esté dispuesto a renunciar en la compatibilidad entre navegadores

+0

Hola jsalonen, gracias por la respuesta. Como la pregunta es de septiembre de 2010, logré resolver eso "recompilando" las páginas xsl. Cuando uso .net en el lado del servidor, hice un script que elimina el xsl: include y concats los archivos de inclusión xsl dentro de los que lo llaman. Estoy bastante seguro de que es posible resolverlo con javascript, pero como dijiste, tomaría mucho trabajo y mucho código solo para administrarlo. Así que acabo de hacer eso en el servidor, por lo que aún puedo reutilizar xsl: plantillas editando los archivos sin procesar, y el javascript leyendo el servidor generó archivos xsl. –

0

Es un problema, pero también puede evitar esto utilizando un ajuste del lado del cliente que precarga cualquier xsl: importación/xsl: incluye en el navegador.

El siguiente es TypeScript (básicamente JavaScript estáticamente estátizado que se compila en JavaScript) y tiene algunas referencias a interfaces que ... uh, no me molesté en eliminar, pero parece funcionar en Chrome (no estoy seguro acerca de otros navegadores) y debería ser suficiente para que cualquiera comience a encontrar una solución.

module DD.Render.DOM.XSLT { 

export class StandardXSLTDOMTransformerFactory implements IXSLTDOMTransformerFactory { 

    constructor(private _domParser:DOMParser, private _document:Document) { 
    } 

    createTransformerFromPath<T>(xslPath: string, xmlTransformer: IStringTransformer<T>, onSuccess: (transformer: IParameterizedDOMTransformer<T>) => void, onFailure: (e: any) => void): void { 
     DD.Util.readXML(
      xslPath, 
      (node: Node) => { 

       // look up any xsl:import or xsl:includes and pull those in too! 
       var onIncludesPreloaded =() => { 
        console.log(node); 
        var transformer = this.createTransformerFromNode(node, xmlTransformer); 
        onSuccess(transformer); 
       }; 
       this.rewriteIncludes(xslPath, node, {}, onIncludesPreloaded, onFailure); 
      }, function (e: any) { 
       onFailure(e); 
      } 
     ); 
    } 

    rewriteIncludes(path:string, node: Node, imported: { [_: string]: boolean }, onRewritten:()=>void, onFailure:(e:any)=>void): void { 
     var result; 
     var element = <Element>node; 
     var importNodes = element.querySelectorAll("import,include"); 
     if (importNodes.length == 0) { 
      onRewritten(); 
      result = false; 
     } else { 
      var rewrittenNodes = 0; 
      // load imports 
      for (var i = 0; i < importNodes.length; i++) { 
       var importElement = <Element>importNodes.item(i); 
       var href = importElement.getAttribute("href"); 
       // TODO work out relative path 
       var relativePath = DD.Util.appendRelativePath(path, href); 
       console.log("importing " + href +" + "+path+" -> "+relativePath); 
       if (!imported[relativePath]) { 
        var e = importElement; 
        imported[relativePath] = true; 
        DD.Util.readXML(relativePath, (importedStylesheet: Node) => { 
         this.rewriteIncludes(relativePath, importedStylesheet, imported, function() { 
          // replace the import with this node (minus stylesheet container) 
          for (var j = 0; j < importedStylesheet.firstChild.childNodes.length; j++) { 
           var templateNode = importedStylesheet.firstChild.childNodes.item(j); 
           if (templateNode.nodeName.indexOf("template") >= 0) { 
            e.parentNode.insertBefore(templateNode, e); 
           } 
          } 
          e.parentNode.removeChild(e); 
          rewrittenNodes++; 
          if (rewrittenNodes == importNodes.length) { 
           if (onRewritten) { 
            onRewritten(); 
           } 
          } 
         }, onFailure); 
        }, onFailure); 
       } else { 
        importElement.parentNode.removeChild(importElement); 
       } 
      } 
      result = true; 
     } 
     return result; 
    } 

    createTransformerFromNode<T>(xsl: Node, xmlTransformer: IStringTransformer<T>): IParameterizedDOMTransformer<T> { 
     var nodeTransformer = new DOMParserDOMTransformer(this._domParser, xmlTransformer); 
     var xsltProcessor = new XSLTProcessor(); 
     xsltProcessor.importStylesheet(xsl); 
     return new StandardXSLTDOMTransformer<T>(xsltProcessor, nodeTransformer, this._document); 
    } 

} 

} 

module DD.Util { 

export function readXML(path: string, onSuccess: (node: Node) => void, onFailure: (e: any) => void) { 
    var xhr = new XMLHttpRequest(); 
    xhr.onload = function() { 
     onSuccess(xhr.responseXML); 
    }; 
    xhr.onerror = function (e: ErrorEvent) { 
     onFailure(e); 
    }; 
    xhr.open("GET", path, true); 
    xhr.send(null); 
} 

export function appendRelativePath(originalPath: string, relativePath: string, originalPathIsDirectory?: boolean) { 
    if (originalPathIsDirectory == null) { 
     originalPathIsDirectory = originalPath.charAt(originalPath.length - 1) == '/'; 
    } 
    if (!originalPathIsDirectory) { 
     // remove file imediately 
     var lastSlash = originalPath.lastIndexOf('/'); 
     if (lastSlash >= 0) { 
      originalPath = originalPath.substring(0, lastSlash + 1); 
     } else { 
      originalPath = ""; 
     } 
    } 
    var slashIndex = relativePath.indexOf('/'); 
    if (slashIndex >= 0) { 
     var relativeDirectory = relativePath.substring(0, slashIndex + 1); 
     var relativeRemainder = relativePath.substring(slashIndex + 1); 
     if (relativeDirectory == "../") { 
      // trim off a directory on the original path 
      if (originalPath.charAt(originalPath.length - 1) == '/') { 
       originalPath = originalPath.substring(0, originalPath.length - 1); 
      } 
      var dirIndex = originalPath.lastIndexOf('/'); 
      if (dirIndex >= 0) { 
       originalPath = originalPath.substring(0, dirIndex + 1); 
      } else { 
       originalPath = ""; 
      } 
     } else { 
      // append to the original path 
      if (originalPath.charAt(originalPath.length - 1) != '/') { 
       originalPath += '/'; 
      } 
      originalPath += relativeDirectory; 
     } 
     appendRelativePath(originalPath, relativeRemainder, true); 
    } else { 
     // append and be done 
     if (originalPath.charAt(originalPath.length - 1) != '/') { 
      originalPath += '/'; 
     }    
     return originalPath + relativePath; 
    } 
} 

} 
1

Tema anterior Lo sé, pero lo volví a verificar aquí para ver si el problema se ha resuelto.

He probado nuevamente y tiene, al menos en la versión 47 de Chrome. Por último puedes usar xsl: incluir.

Cuestiones relacionadas