Ich habe eine Anwendung geschrieben, die eine Pipeline von 15 XSL-Stylesheets verwendet, und ich fange an, daran zu arbeiten, die Leistung zu optimieren. Es ist portabel, sodass es sowohl in der Webbrowser-Umgebung als auch auf dem Desktop ausgeführt werden kann. Auf dem Desktop denke ich, dass es sinnvoll sein könnte, die Stylesheets als Pipeline mit mehreren Transformationen zu trennen, da jede einzelne Transformation in einem eigenen Thread ausgeführt werden kann, was bei CPUs mit mehreren Kernen sehr effizient sein kann. Die Browserumgebung ist jedoch nicht nur single-threaded, in den meisten Browsern erfordert die XSL-Verarbeitungs-API, die für JavaScript verfügbar gemacht wird, das Ergebnis jeder einzelnen Transformation zurück in ein DOM-Objekt zu analysieren, was ineffizient erscheint. Ich denke, es wäre daher von Vorteil, alle Stylesheets in einem einzigen Stylesheet zu kombinieren, wenn dies im Kontext der Browserumgebung möglich ist. Ich habe eine Idee, wie dies mit exsl erreicht werden kann: Node-Set (die meisten Browser unterstützen), aber es ist mir nicht klar, ob die Technik, die ich mir vorstelle, verallgemeinerbar ist. Gibt es eine allgemeine Technik zum Transformieren einer Pipeline von XSL-Stylesheets in ein einziges XSL-Stylesheet, so dass die Semantik der vollständigen Pipeline erhalten bleibt? Eine automatisierte Lösung wäre ideal.Gibt es eine Technik, um eine Pipeline von XSL-Transformationen zu einer einzigen Transformation zu kombinieren?
Antwort
Es gibt eine Technik, die es ermöglicht, unabhängige Transformationen zusammenzufassen, wobei die Ausgabe der k-ten Transformation die Eingabe der (k + 1) -ten Transformation ist. Hier
ist ein einfaches Beispiel:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="http://exslt.org/common"
exclude-result-prefixes="ext xsl">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<xsl:variable name="vrtfPass1">
<xsl:apply-templates select="node()"/>
</xsl:variable>
<xsl:apply-templates mode="pass2"
select="ext:node-set($vrtfPass1)/node()"/>
</xsl:template>
<xsl:template match="/*">
<xsl:copy>
<xsl:copy-of select="@*"/>
<one/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="node()|@*" mode="pass2">
<xsl:copy>
<xsl:apply-templates select="node()|@*" mode="pass2"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*/one" mode="pass2" >
<xsl:call-template name="identity"/>
<two/>
</xsl:template>
</xsl:stylesheet>
wenn diese Transformation auf das folgende XML-Dokument angewendet wird:
<doc/>
das gewünschte Ergebnis (der erste Durchgang addds das Element <one/>
als ein Kind des obersten Elements, dann fügt der zweite Durchlauf ein weiteres Kind hinzu, , immediately after the element
`das wurde in dem ersten Durchgang erzeugt) ist hergestellt:
<doc>
<one/>
<two/>
</doc>
Es gibt eine sehr passende Vorlage/Funktion in FXSL, dies zu tun: das ist die compose-flist
Vorlage. Es verwendet als Parameter ein initiales Datenargument und N Funktionen (Templates) und erzeugt die verkettete Zusammensetzung dieser Funktionen/Templates. Hier
ist der Test Beispiel aus der FXSL Bibliothek:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:f="http://fxsl.sf.net/"
xmlns:myFun1="f:myFun1"
xmlns:myFun2="f:myFun2"
xmlns:ext="http://exslt.org/common"
exclude-result-prefixes="xsl f ext myFun1 myFun2"
>
<xsl:import href="compose.xsl"/>
<xsl:import href="compose-flist.xsl"/>
<!-- to be applied on any xml source -->
<xsl:output method="text"/>
<myFun1:myFun1/>
<myFun2:myFun2/>
<xsl:template match="/">
<xsl:variable name="vFun1" select="document('')/*/myFun1:*[1]"/>
<xsl:variable name="vFun2" select="document('')/*/myFun2:*[1]"/>
Compose:
(*3).(*2) 3 =
<xsl:call-template name="compose">
<xsl:with-param name="pFun1" select="$vFun1"/>
<xsl:with-param name="pFun2" select="$vFun2"/>
<xsl:with-param name="pArg1" select="3"/>
</xsl:call-template>
<xsl:variable name="vrtfParam">
<xsl:copy-of select="$vFun1"/>
<xsl:copy-of select="$vFun2"/>
<xsl:copy-of select="$vFun1"/>
</xsl:variable>
Multi Compose:
(*3).(*2).(*3) 2 =
<xsl:call-template name="compose-flist">
<xsl:with-param name="pFunList" select="ext:node-set($vrtfParam)/*"/>
<xsl:with-param name="pArg1" select="2"/>
</xsl:call-template>
</xsl:template>
<xsl:template match="myFun1:*" mode="f:FXSL">
<xsl:param name="pArg1"/>
<xsl:value-of select="3 * $pArg1"/>
</xsl:template>
<xsl:template match="myFun2:*" mode="f:FXSL">
<xsl:param name="pArg1"/>
<xsl:value-of select="2 * $pArg1"/>
</xsl:template>
</xsl:stylesheet>
wenn diese Transformation auf jedem XML-Dokument angewendet wird (nicht benutzt), der wollte, korrekte Ergebnis wird hergestellt:
Compose:
(*3).(*2) 3 =
18
Multi Compose:
(*3).(*2).(*3) 2 =
36
Beachten Sie: In XSLT 2.0 und höher ist keine xxx:node-set()
Erweiterung erforderlich, und alle der Kette Ed-Transformationen können in einer realen Funktion enthalten sein.
Extrem gründlich. Danke für Ihre Antwort! – jbeard4
Ein Ansatz ist, Modi zu verwenden http://www.w3.org/TR/xslt#modes aber Sie haben Recht, dass das erfordert jeder Schritt in eine Variable umzuwandeln und eine Knotenmenge Erweiterungsfunktion zu nutzen, um der Lage sein, den nächsten Schritt zu den variablen Inhalte anzuwenden.
- 1. Gibt es eine übliche Technik zum Zeichnen einer "dehnbaren" Linie
- 2. Gibt es eine Möglichkeit, Changeset in Liquibase zu kombinieren?
- 3. Gibt es eine Möglichkeit, diese fast identischen Klassen zu einer zu kombinieren?
- 4. gibt es eine gute Möglichkeit, Stream Manipulatoren zu kombinieren?
- 5. gibt es eine Möglichkeit, Qt-Creator + Boost Library zu kombinieren?
- 6. Gibt es eine Möglichkeit, mehrere Stildateien zu definieren, um einen einzigen großen in Android zu vermeiden?
- 7. Gibt es eine Möglichkeit, Namespaces während einer XSL-Transformation zu ignorieren?
- 8. Gibt es eine integrierte Methode, um die Eigenschaften von zwei Objekten zu einem einzigen Objekt zusammenzuführen?
- 9. Gibt es eine Möglichkeit, zwei Aggregatfunktionen in MySQL zu kombinieren, um unterschiedliche Werte zu erhalten?
- 10. Gibt es eine Möglichkeit, ein SVG USE nachträglich modifizierbar (oder eine andere Technik) zu machen?
- 11. Gibt es eine Möglichkeit, zwei UI-Elemente zu kombinieren?
- 12. Gibt es eine Möglichkeit, Knotenmodule mit ähnlichen Funktionen zu kombinieren?
- 13. Gibt es eine Möglichkeit, zwei Optionen zu "kombinieren"?
- 14. Ist es möglich, eine Flexions- und Umgebungssuche in einer einzigen CONTAINSTABLE-Suchbedingung zu kombinieren?
- 15. Gibt es eine Möglichkeit, um nur Dateien zu glob()?
- 16. Wie eine Pipeline von data.table zu bauen, um data.table
- 17. Eine Technik für die Reaktionsfähigkeit mit CSS-Transformation Skala
- 18. Gibt es eine Alternative zu Android ViewOverlay?
- 19. Algorithmus für bitweise Transformation, um eine Gleichung zu erfüllen
- 20. Was ist die richtige Technik, um eine Ausnahme von einem Servlet zu einer Standardfehler-JSP umzuleiten?
- 21. Gibt es eine Mosquitto-Einstellung, um doppelte Nachrichten zu behalten?
- 22. Gibt es eine Möglichkeit, eine reine virtuelle Funktion zu "löschen"?
- 23. Gibt es einen Befehl in Vim/gVim, um zwei oder mehr Registerkarten zu einem einzigen geteilten Fenster zu kombinieren?
- 24. Gibt es eine Möglichkeit, diese beiden Methoden in einer Methode oder überladenen Methoden zu kombinieren?
- 25. Gibt es eine Möglichkeit, Json von einer Subdomain zu laden?
- 26. Gibt es eine Möglichkeit, Mehrfacheinspritzung zu propagieren?
- 27. Gibt es eine Möglichkeit, CSS-Transformation zu verwenden und Kinderelemente nicht zu beeinflussen
- 28. Gibt es einen Befehl, um eine Liste von Schlüsseln zu übergeben und eine Liste von Hashes in Redis zu erhalten?
- 29. eine Möglichkeit, Hintergrundklassen zu kombinieren?
- 30. Gibt es eine Möglichkeit, eine Github-PR-Zusammenführung zu erhalten, um eine EC2-Instanz zu starten?
Gute Frage, +1. Sehen Sie meine Antwort für eine ausführliche Erklärung und für zwei Beispiele der vorgeschlagenen Lösung. –