xsl: include и xsl: param в Google Chrome с плагином преобразования jQuery - PullRequest
8 голосов
/ 06 сентября 2010

Я пытался использовать XSL с Google Chrome, но безуспешно.
Я читал, что в Chrome есть некоторые ошибки с XSLT, и одна из них заключается в том, что он не поддерживает xsl: include. Ошибка может быть проверена здесь: http://code.google.com/p/chromium/issues/detail?id=8441.
После некоторых исследований я нашел новую версию плагина преобразования от Daer System, и он заставляет xsl: include работать на Chrome.

Плагин jQuery Transform можно найти по адресу http://plugins.jquery.com/project/Transform

Теперь моя проблема:
Я использую включение по умолчанию в некоторых шаблонах xsl, и это включение использует параметр, который передается первому уровню.

Таким образом, у меня есть шаблон top.xsl , который объявляет [xsl: param name = "param" /], и я использую этот параметр с includes.xsl, который вызывается первым с помощью [xsl: include href = "includes.xsl"]. Это работает как в Firefox, так и в Internet Explorer, но не в Chrome. Здесь я увидел вопрос о stackoverflow, когда какой-то парень переписал функцию исправления webkit из плагина, но она не работает с xsl: param таким образом.

Кто-нибудь знает, как использовать [xsl: param] в Google Chrome, как это?

Ответы [ 3 ]

1 голос
/ 17 декабря 2015

Старая тема, я знаю, но проверил здесь, чтобы увидеть, была ли проблема решена.

Я протестировал снова, и это, по крайней мере в версии 47 ChromeНаконец вы можете использовать xsl: include.

1 голос
/ 31 мая 2011

Ваша проблема в том, что Google Chrome (= Chromium) не поддерживает xsl:include

Недостаток этой функции хорошо отмечен в проекте Chromium, о котором говорилось в "Проблема 8441: XSLTProcessor в JS не разрешает xsl: include for http" . Кажется, что проблема вызвана некоторой архитектурной проблемой в WebKit (движок рендеринга, используемый в Chrome). Поскольку эта проблема возникла в WebKit, ошибка помечена как WontFix - исправление будет предоставлено (надеюсь) в будущем, поскольку исходная проблема в WebKit будет решена.

Я вижу три возможных варианта решения этой проблемы для вас:

  1. Подождите, пока WebKit / Chrome не получит исправление, решающее эту проблему (потенциально это займет много времени ...)
  2. Создать / найти хак, который обходит эту проблему, например, эмулируя xsl:include для Chrome / Webkit (потенциально требует много работы / разработки хака)
  3. Попытайтесь найти способ написания своего программного обеспечения таким образом, чтобы вам не требовалась эта особая функция XSL (или запустите XSL-преобразование на стороне сервера)

Моя рекомендация: избегайте использования xsl: include с xsl: param на стороне клиента, если вы не хотите отказаться от кросс-браузерной совместимости

0 голосов
/ 20 января 2014

Это неприятно, но вы также можете обойти это, используя клиентскую оболочку, которая предварительно загружает любые xsl: import / xsl: include в браузер.

Ниже приведен TypeScript (в основном статически типизированный JavaScript, который компилируется в JavaScript) и содержит несколько ссылок на интерфейсы, которые ... эээ, я не удосужился удалить, но, похоже, работает в Chrome (не уверен в других браузерах) и должно быть достаточно, чтобы кто-нибудь начал с решения.

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;
    }
}

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...