2013-04-07 18 views
8

Ich dachte, ich sah einen Fehler in einer Antwort auf this question, und wies darauf hin. Mir wurde gesagt, ich sei falsch, und meine Antwort wurde später gelöscht.Passende untergeordnete Elemente in XSL

Ich sehe immer noch nicht, wie ich falsch lag. Deshalb poste ich hier und hoffe, dass jemand mein Missverständnis erklären kann.

Die Antwort, die ich antwortete, erklärte die Verwendung von Anwenden-Vorlagen. Es enthielt die folgende XML und XSL, das beschreibt, wie die Vorlagen abgestimmt werden würde:

<!-- sample XML snippet --> 
<xml> 
    <foo /><bar /><baz /> 
</xml> 

<!-- sample XSLT snippet --> 
<xsl:template match="xml"> 
    <xsl:apply-templates select="*" /> <!-- three nodes selected here --> 
</xsl:template> 

<xsl:template match="foo"> <!-- will be called once --> 
    <xsl:text>foo element encountered</xsl:text> 
</xsl:template> 

<xsl:template match="xml/*"> <!-- will be called twice --> 
    <xsl:text>other element countered</xsl:text> 
</xsl:template> 

Mein Kommentar war, dass die letzte Vorlage sollte in sein:

<xsl:template match="*"> <!-- will be called twice --> 
    <xsl:text>other element countered</xsl:text> 
</xsl:template> 

weil der aktuelle Knoten bereits <xml>

wurde mir gesagt:

Nein, xml/* ist ein Muster, das Kind Elemente Spiele ein Element mit der Name xml.

Testen der ursprünglichen Antwort

jedoch mit dieser XML:

<xml> 
    <foo /><bar /><baz /> 
</xml> 

Und dieses XSL-Stylesheet (Füllen der Schnipsel oben aus):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="text"/> 

<xsl:template match="xml"> 
    <xsl:apply-templates select="*" /> <!-- three nodes selected here --> 
</xsl:template> 

<xsl:template match="foo"> <!-- will be called once --> 
    <xsl:text>foo element encountered.&#xa;</xsl:text> 
</xsl:template> 

<xsl:template match="xml/*"> <!-- will be called twice --> 
    <xsl:text>other element countered.&#xa;</xsl:text> 
</xsl:template> 

</xsl:stylesheet> 

ich :

other element countered. 
other element countered. 
other element countered. 

meine 'korrigiert' Version

Wenn ich die letzte Vorlage ersetzen mit Test:

<xsl:template match="*"> <!-- will be called twice --> 
    <xsl:text>other element countered.&#xa;</xsl:text> 
</xsl:template> 

wie pro meine Antwort, die ich erhalten:

foo element encountered. 
other element countered. 
other element countered. 

, die angezeigt werden soll sei richtig.

Ich hoffe, meine Frage bricht keine Richtlinien, aber ich kann nicht sehen, dass ich falsch liege und hoffe, dass jemand es ausführlicher erklären kann.

PS. Ich fürchte, meine ursprüngliche Antwort auf die andere Frage wurde als Antwort gepostet, nicht als Kommentar, da ich noch nicht genügend Punkte habe, um Kommentare zu schreiben. Ich war mir nicht sicher, was das Beste war ...

+1

Danke für die Suche nach diesem dummen Fehler von mir, es ist jetzt in den anderen Thread behoben. Dies wurde von allen anderen unbemerkt, die die Antwort über die Jahre hinweg betrachteten. – Tomalak

Antwort

6

Dies ist korrekt, nach der rules on the default priority of templates. Eine Vorlage, die mit foo übereinstimmt, hat die Standardpriorität 0, eine passende * hat die Standardpriorität -0,5, aber eine übereinstimmende xml/* hat die Standardpriorität 0,5. Die Vorlage xml/* gilt als spezifischer als die foo Eins, so dass es gewinnt, wenn beide übereinstimmen könnten.

Sie waren also richtig, dass das Match Ausdruck der Vorlage benötigt * zu sein, anstatt xml/*, aber nicht aus dem richtigen Grund - eine xml/* Vorlage kann Spiel für einen apply-templates select="*" wenn der aktuelle Knoten xml ist, und es gilt zu eines dieser ausgewählten Elemente (da sie alle untergeordnete Elemente von xml sind), außer wenn eine andere Vorlage mit einer expliziten priority größer als 0,5 vorhanden ist, die Vorrang haben kann.

4

Ich war die Person, die sagte, dass Sie in dem anderen Thread falsch waren, und nachdem ich die Sache näher betrachtet habe, kann ich sehen, dass Sie richtigerweise darauf hingewiesen haben, dass Tomalak einen Fehler gemacht hat, aber nicht aus den Gründen, die Sie angegeben haben (wenn ich deinen Kommentar richtig verstehe). match="xml/*"entspricht untergeordnete Knoten des Elements <xml>, ob der aktuelle Kontext der <xml>-Knoten war oder nicht, wenn apply-templates aufgerufen wurde. In einem match="" Ausdruck ist der "aktuelle Knoten" der Knoten, auf dem Vorlagen angewendet werden, nicht der Kontext, in dem apply-templates aufgerufen wurde. In dieser Vorlage wäre also der aktuelle Knoten foo, bar und baz. Sie können von Ihrem eigenen Experiment oben beobachten, dass xml/* gelingt, untergeordnete Elemente von xml zu entsprechen, aber in der Tat passt sie mehr als Tomalak sagt, es wird.

Das Problem mit match="xml/*" ist, dass es zu spezifisch ist und hat den gegenteiligen Effekt von dem, was ich denke, Tomalak beabsichtigt. Es scheint, dass er damit gemeint war, ein Kinderspiel für Kinder von xml, die sonst nicht übereinstimmen, aber wie Ian Roberts erklärt, diese Vorlage endet mit einer höheren Priorität als die foo Vorlage, und fängt alle Kinder von der xml Knoten.

Ich weiß, es ist frustrierend, jetzt nicht in der Lage zu sein, eigene Kommentare zu schreiben, aber bald genug werden Sie es tun. Und es ist akzeptabel, eine eigene neue Frage zu erstellen, um eine Frage zu einem anderen Thread zu stellen. Sie sollten nur keine Antworten erstellen, um andere Antworten zu kommentieren.

+0

+1 Nun, das ist peinlich. :) – Tomalak

Verwandte Themen