2010-09-06 9 views
8

Próbowałem używać XSL w Google Chrome, ale bez powodzenia.
Przeczytałem, że Chrome ma kilka błędów z XSLT, a jednym z nich jest to, że nie obsługuje xsl: include. Błąd można sprawdzić tutaj: http://code.google.com/p/chromium/issues/detail?id=8441.
Po przeprowadzeniu badań znalazłem nową wersję wtyczki do przekształcania autorstwa Daer System, która sprawia, że ​​xsl: include działa w Chrome.xsl: include i xsl: param w Google Chrome, z wtyczką jQuery transform

jQuery Transform plugin można znaleźć od http://plugins.jquery.com/project/Transform

Teraz mój problem jest:
używam domyślnego obejmują w niektórych szablonów XSL, a to m.in. używa parametru, który jest przekazywany do górnego poziomu pierwszego.

więc jej jak mam top.xsl szablon, który deklaruje [xsl: param param name = "" /], a następnie użyć tej param z included.xsl, która jest wywoływana przez 1 jeden z [xsl: include href = "included.xsl"]. Działa to zarówno w Firefoksie, jak i Internet Explorerze, ale nie w Chrome. Widziałem tu pytanie na stackoverflow, gdzie jakiś facet napisał ponownie funkcję naprawy webkita z wtyczki, ale nie działa z xsl: param w ten sposób.

Czy ktoś wie, jak używać [xsl: param] w Google Chrome?

+0

Wygląda na to, że tak jest tylko podczas uruchamiania transformacji za pośrednictwem javascript. Jak widać, moja strona z obsługą XML/XSLT działa: www.aranedabienesraices.com.ar –

+0

Cześć Alejandro, tak, to robi transformacje javascript. Muszę to zrobić za pośrednictwem javascript. –

+0

user357812: proszę wyjaśnić: w jaki sposób link ten jest odpowiedni dla tego pytania? – jsalonen

Odpowiedz

1

Twój problem polega na tym, że Google Chrome (= Chrom) nie obsługuje xsl:include

brak tej funkcji jest również zauważyć w projekcie Chromium jako podniesiony w "Issue 8441: XSLTProcessor in JS does not permit xsl:include for http". Wygląda na to, że problem spowodowany jest jakimś problemem architektonicznym w WebKit (silniku renderującym używanym w Chrome). Ponieważ ten problem pochodzi od WebKit, błąd jest oznaczony jako WontFix - poprawka zostanie dostarczona (miejmy nadzieję) w przyszłości, gdy oryginalny problem w WebKit zostanie rozwiązany.

widzę trzy możliwe alternatywy, jak ten problem może być rozwiązany za Ciebie:

  1. Odczekać aż WebKit/Chrome pobiera poprawkę, która rozwiązuje ten problem (potencjalnie trwa długo ...)
  2. Utwórz/znaleźć hack który działa wokół tego problemu, na przykład poprzez emulację jakoś xsl:include dla Chrome/Webkit (potencjalnie wymaga dużo pracy/rozwój hack)
  3. spróbować znaleźć sposób pisania oprogramowania I sposób na które nie wymagają tej konkretnej funkcji XSL (alternatywnie uruchomić transformacji XSL na stronie serwera)

Moja rada: unikać xsl: include z xsl: param po stronie klienta, chyba że jesteś skłonny dać na kompatybilność z różnymi przeglądarkami

+0

Hej jsalonen, dzięki za odpowiedź. Ponieważ pytanie pochodzi z sep, 2010, udało mi się rozwiązać to przez "rekompilację" stron xsl. Kiedy używam .net po stronie serwera, stworzyłem skrypt, który usuwa plik xsl: include i konkluduje pliki dołączane do xsl wewnątrz tych, które go nazywają. Jestem prawie pewny, że można go rozwiązać za pomocą javascript, ale jak powiedziałeś, potrzeba by dużo pracy i dużo kodu, aby to zarządzać. Po prostu zrobiłem to na serwerze, dzięki czemu nadal mogę ponownie używać xsl: szablonów do edycji plików raw, a javascript do odczytu plików xsl wygenerowanych przez serwer. –

0

To jest problem, ale można również obejść ten problem, używając podkładki po stronie klienta, która wstępnie ładuje pliki xsl: import/xsl: includes w przeglądarce.

Oto TypeScript (w zasadzie statycznie napisany skrypt JavaScript, który kompiluje się do JavaScript) i ma kilka odwołań do interfejsów, które ... ja, nie zawracałem sobie głowy usuwaniem, ale wygląda na to, że działa w Chrome (nie mam pewności co do innych przeglądarek) i powinno wystarczyć, aby ktokolwiek zaczął korzystać z rozwiązania.

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

Stary temat, który znam, ale został sprawdzony tutaj, aby sprawdzić, czy problem został rozwiązany.

Przetestowałem ponownie i przynajmniej w wersji 47 Chrome. W końcu możesz użyć xsl: include.