2010-12-16 10 views

Antwort

7

ich denke, das einige hat, was als mit Verständnis push vs. pull Stil Verarbeitung zu tun, nur xsl:for-each oder xsl:template match="..." zu vergleichen. Sie sehen oft Programmierer aus einer anderen Disziplin mit vielen xsl:if, xsl:choose und for-Schleifen, wenn das Problem auf eine elegantere XSLTish-Art gelöst werden konnte.

Aber auf die Frage:Meiner Meinung nach, wenn Sie mit xsl:apply-templates mit xsl:for-each anstelle der Verarbeitung der Daten betrachten Sie zu überdenken müssen. Es gibt Fälle, in denen eine For-Schleife in XSLT geeignet ist, aber immer, wenn eine übereinstimmende Vorlage dasselbe tun würde, sind Vorlagen der richtige Weg. Nach meiner Erfahrung können Sie die meisten xsl:for-each mit einer xsl:apply-templates stattdessen tun.

Einige Vorteile, wie ich es von mit passenden Vorlagen über eine for-Schleife zu sehen sind:

  • Die Stylesheets sind leichter zu pflegen und wenn Quelldaten ändern zu verlängern besonders.
  • Wie @chiborg erwähnt, können Vorlagen wiederverwendet werden, da sie nicht in eine bestimmte Vorlage integriert sind. Zusammen mit xsl:next-match in XSLT 2.0 können Sie Vorlagen auf leistungsstarke Weise miteinander verknüpfen.
  • Sie müssen das Verhalten, das bereits in allen XSLT-Prozessoren eingebaut ist, nicht nachahmen. Verwenden Sie xsl:apply-templates und lassen Sie den Prozessor für Sie arbeiten.
  • Auch finde ich es einfacher, ein Push-Stylesheet zu verstehen und zu debuggen. Wenn Sie Ihre Stylesheet-Informationen in kleine Templates unterteilen, die ein oder mehrere Dinge tun, und spezifische Matching-Muster schreiben, ist es einfach zu sehen, welches Template was macht und die Ursache des Problems aufzeigt.
+0

Ich stimme Ihnen zu, dass es einfach ist zu sehen, was in den einzelnen Vorlagen passiert, aber es ist schwieriger zu sehen, welche Vorlage in welcher Reihenfolge (mit Anwendungsvorlagen) aufgerufen wird. – LarsH

+0

@LarsH: Das ist, was Sie Oxygens wunderbar Debuggen für ... verwenden;) –

+0

Sie haben Recht, ich tue :-) und es ist manchmal ein Lebensretter. Aber das Debugging kann nur helfen, wenn Sie die XML-Eingabedaten zur Hand haben ... und es kann nur für diese bestimmte Dateninstanz helfen. Wenn Sie jedoch das Stylesheet mit Verständnis lesen können, können Sie viel mehr Rückschlüsse darüber ziehen, was passieren kann und was nicht, unabhängig von der jeweiligen Eingabe, als wenn Sie das Stylesheet nicht mit Verständnis lesen können. – LarsH

1

for-each kann nur innerhalb einer Stelle in Ihrer Vorlage verwendet werden. Vorlagen können mit verschiedenen apply-templates Aufrufen wiederverwendet werden. Ich verwende meistens Templates anstelle von for-each wegen der zusätzlichen Flexibilität.

3

Es ist nicht wirklich wichtig, aber man kann über sie für die folgenden Daumen von Regeln, die ich gefunden denken:

  • Wenn der Code hängt vom Kontext ab Position (Position()), Setzen Sie es in eine <xsl:for-each>.
  • Wenn der Code vom Kontext Knoten (oder einem beliebigen Pfad) abhängig ist, geben Sie ihn in eine passende Vorlage ein.
  • Verwenden Sie andernfalls eine benannte Vorlage.

Referenz und lesen Sie mehr unter: http://www.jenitennison.com/blog/node/9

1

Dies sind verschiedene XSLT-Anweisungen abzuschließen.

Mehr als Push vs. Pull-Stil, das ist mehr wie Iteration vs Rekursion.

xsl:for-each ist ein Iterator-Befehl mit allen Vorteilen und Einschränkungen der Iteration in einem stateless deklarativen Paradigma: ein guter Prozessor sollte den Aufruf-Stack nicht polieren.

xsl:apply-templates ist eine allgemeine Rekursionsanweisung. Allgemein in dem Sinne, dass es mächtiger ist als xsl:call-template: Sie "werfen" die ausgewählten Knoten auf den Mustervergleichsmechanismus, einen wirklich "dynamischen Funktionsaufruf".

5

Sowohl das 'für-jeden' und 'Template' werden verwendet, um die Knoten von XML in die XSL abzurufen. Aber was ist der Unterschied zwischen ihnen im Grunde genommen in

Hier sind einige der wichtigsten Unterschiede:

  1. xsl:apply-templates ist viel reicher und tiefer als xsl:for-each, sogar einfach, weil wir weiß nicht, welcher Code auf die Knoten von die Auswahl angewendet wird - im allgemeinen Fall wird dieser Code für verschiedene Knoten des n unterschiedlich sein ode-Liste.

  2. Der Code, die kann so geschrieben werden, werden angewandt werden, nachdem die xsl:apply template s und von Menschen geschrieben wurde, der den ursprünglichen Autor nicht kennen.

Die FXSL library ‚s Implementierung von Funktionen höherer Ordnung (HOF) in XSLT wäre nicht möglich, wenn XSLT nicht die <xsl:apply-templates> Anweisung haben.

Zusammenfassung: Vorlagen und die <xsl:apply-templates> Anweisung ist, wie XSLT implementiert und Polymorphismus behandelt.

Referenz: Schau dir das ganze Thema: http://www.stylusstudio.com/xsllist/200411/post60540.html

+0

In "diesem ganzen Thread" schreibt Dimitre nichts, was nicht schon auf dieser SO-Seite steht. – Roland

+0

@Roland, "Dieser ganze Thread" wird hier als Referenz zitiert, die die Antworten einiger heller Leute zusammenbringt. Es gibt keine Aussage in dieser Antwort, die besagt, dass man etwas anderes finden würde. –

10

ich mit den anderen Antworten im Allgemeinen zustimmen, aber ich werde sagen, dass in meiner Erfahrung, ein Stylesheet mit xsl:for-each geschrieben viel einfacher sein kann, zu lesen, zu verstehen und zu pflegen als eine, die stark xsl:apply-templates ... Insbesondere xsl:apply-templates mit einer impliziten Auswahl (oder eine sehr generische Auswahl wie select="node()").

Warum? Weil es sehr einfach ist zu sehen, was ein Für-Jeder tun wird. Mit Apply-Templates müssen Sie im Wesentlichen (a) über alle möglichen XML-Eingaben Bescheid wissen (was einfacher ist, wenn Sie ein Schema haben, aber dann müssen Sie das Schema noch verdauen, und oft haben Sie kein Schema Insbesondere für vorübergehende XML-Zwischendaten, die auf einer Stufe einer Pipeline gesendet werden, und selbst wenn Sie ein Schema haben, gibt Ihnen Ihr Entwicklungsframework (z. B. ein ESB oder CMS) möglicherweise keine Möglichkeit, Ihr XML an jedem Punkt Ihrer Pipelines zu validieren. Wenn sich also ungültige Daten einschleichen, werden Sie nicht sofort benachrichtigt), so dass Sie vorhersagen können, welche Arten von Knoten ausgewählt werden (z. B. Kinder des Kontextknotens). und (b) schauen Sie sich jede Vorlage im Stylesheet an, um zu sehen, welche Vorlage mit den Knoten mit der höchsten Priorität übereinstimmt (und in der Reihenfolge der Dokumente zuletzt ist).Die Reihenfolge der Verarbeitung kann auch über die Dateien hinweg oder über verschiedene Dateien (importiert oder eingeschlossen) hinausgehen. Dies kann es sehr schwierig machen zu "sehen", was vor sich geht.

Wohingegen mit einem for-each, Sie genau wissen, welcher Code instanziiert wird: der Code innerhalb der for-each. Und da for-for jedes einen expliziten Select-Ausdruck erfordert, ist es wahrscheinlicher, dass Sie ein schmaleres Feld haben, um zu erraten, welche Knoten gefunden werden können.

Jetzt leugne ich nicht, dass Anwendung-Vorlagen viel mächtiger und flexibler als für-jedes ist. Das ist genau der Punkt: Konstrukte, die leistungsfähiger und flexibler sind, sind auch schwieriger einzuschränken, zu verstehen und zu debuggen (und Sicherheitslücken zu verhindern). Es ist die Rule of Least Power: "Leistungsfähige Sprachen (oder in diesem Fall Konstrukte) verhindern die Wiederverwendung von Informationen." (Also discussed here.)

Wenn Sie Anwendungsvorlagen verwenden, ist jede Vorlage modularer und daher in sich wiederverwendbar, aber das Stylesheet ist komplexer und die Interaktion zwischen Vorlagen ist weniger vorhersehbar. Wenn Sie for-each verwenden, ist der Verarbeitungsablauf leicht vorhersehbar und sichtbar.

Mit <xsl:apply-templates /> (oder mit <xsl:for-each select="node()"/>), wenn sich die Struktur der Eingabe-XML ändert, ändert sich das Verhalten des Stylesheets ohne die Überprüfung des Entwicklers. Ob dies gut oder schlecht ist, hängt davon ab, wie viel Voraussicht Sie in Ihr Stylesheet gelegt haben und wie gut die Kommunikation zwischen dem XML-Schema-Entwickler und dem Stylesheet-Entwickler ist (wer kann dieselbe Person sein oder zu verschiedenen Organisationen gehören).

Also für mich ist es ein Urteilsspruch. Wenn Sie über dokumentenorientiertes XML wie HTML verfügen, bei dem viele der Elementtypen in einer Hierarchie beliebiger Hierarchieebenen wirklich viele verschiedene Untertypen haben können, hängt die Verarbeitung eines bestimmten Elementtyps nicht sehr oft von seinem Kontext ab Dann ist das Anwenden von Templates absolut notwendig. Auf der anderen Seite, wenn Sie "datenorientiertes" XML mit einer vorhersagbaren Struktur haben, wo Sie nicht oft den gleichen Elementtyp haben, der dasselbe in verschiedenen Kontexten bedeutet, denn jeder kann viel einfacher zu lesen und zu debuggen sein (und deshalb richtig und schnell schreiben).

+1

+1 Ich denke, das ist eine ausgewogenere Bewertung als die angenommene Antwort – PandaWood

+0

@PandaWood, danke. – LarsH

1

Eine Verwendung von for-each Ich habe nicht erwähnt gesehen: Sie können es verwenden, um den Kontextknoten zu einem anderen Dokument zu wechseln. Ich habe es verwendet, um Daten-XML in ein HTML-Eingabeformular umzuwandeln. Die Vorlage, die einem Datenfeld entsprach, enthielt eine For-Each, die einen einzelnen Knoten auswählte: die xs:element in der XSD, die das zu transformierende Datenfeld beschreibt.

Mithilfe der Beschreibung in der XSD kann ein Datenfeld in eine Optionsfeldgruppe, eine Dropdown-Box oder eine einfache Texteingabe umgewandelt werden. Ohne for-each konnte ich nicht gleichzeitig durch die beiden Dokumente gehen.

Im Allgemeinen bevorzuge ich passende Vorlagen. Ich finde, dass es der Idee einer einzigen Transformation entspricht, die auf einmal besser angewendet wird als jeder Knoten, dann der nächste, dann der nächste, usw. Aber das ist natürlich eine persönliche Vorliebe.

+0

+1. Das Festlegen des Kontextknotens ist eine wichtige Verwendung von 'for-each' - gutem Punkt. Und oft ist das der prägnanteste und klarste Weg, den Kontextknoten zu setzen. Sie können jedoch auch 'Apply-Templates' verwenden, um dasselbe zu tun. Mit anderen Worten, ich glaube nicht, dass es nicht möglich ist, zwei Dokumente gleichzeitig zu durchlaufen, ohne 'for-each' zu verwenden. Denken Sie daran, dass "Anwendungsvorlagen" Modi und Parameter verwenden können. – LarsH

Verwandte Themen