2010-12-23 5 views
1

Was ist der schnellste Weg zu finden, ob der aktuelle Knoten in Pfad eines Knotens mit einem bestimmten Attribut ist, da diese XML-Struktur:Überprüfen Sie, ob Knoten in Pfad eines Knotens mit einem bestimmten Attribut

<root> 
<item> 
    <item name="x"> 
     <item></item> 
     <item name="y"></item> 
     <item></item> 
    </item> 
    <item></item> 
    <item></item> 
</item> 
<item> 
    <item name="z"></item> 
    <item></item> 
</item> 

Ich habe eine xslt-Variable, um mir zu sagen, was der aktuelle aktive Knoten ist.

Ich möchte Code ausführen, wenn der aktuelle Knoten im Pfad des Knotens mit dem @ Name x ist.

Wenn also der aktive Knoten das Element mit @name y ist, sollte der Code ausgeführt werden, wenn der aktuelle aktive Knoten ein Element mit @name z ist, sollte dies nicht der Fall sein.

Meine beste Lösung so weit ist:

ancestor-or-self::item[@name = 'x'] 

Aber da es 30k + Artikel Knoten dies für immer nimmt zu machen, ist es ein schnellerer Weg? (XSLT/XPATH 2 ist keine Option)

+0

Sie meinen XSLT/XPATH Version 2.0 ist keine Option, aber XSLT/XPATH 1.0 ist OK? – khachik

+0

@Hans Skov: Der "Ahnen-oder-Selbst" sollte nicht so schwer in der Leistung sein. Das Problem muss in Ihrem Transformationsmuster liegen: Wenn Sie dies für jeden Knoten ausführen, sollte dies zu Lasten der Leistung gehen. –

+0

@ Alejandro - Ich denke, er sagte, dass, weil er 30k + Operationen hat, die Kosten steigen, obwohl ich vorschlagen würde, dass sich das nicht ändern wird. Ahnen-oder-Selbst ist die richtige Lösung, glaube ich. – annakata

Antwort

2

Der beste Ansatz hängt stark von der gesamten Transformation ab.

Man könnte annehmen, dass Musteranpassung optimiert ist, so:

<xsl:template match="item[@name='x']//*"> 

Auch Sie Modi wie verwenden:

<xsl:template match="item[@name='x']"> 
    <xsl:apply-templates mode="descandants-in-path"> 
</xsl:template> 

<xsl:template match="node()" mode="descandants-in-path"> 

Oder ein Parameter wie:

<xsl:template match="item[@name='x']"> 
    <xsl:apply-templates> 
     <xsl:with-param name="pIsInPath" select="true()"/> 
    </xsl:apply-templates> 
</xsl:template> 

<!-- Tunnel rule --> 
<xsl:template match="*"> 
    <xsl:param name="pIsInPath"/> 
    <xsl:apply-templates> 
     <xsl:with-param name="pIsInPath" select="$pIsInPath"/> 
    </xsl:apply-templates> 
</xsl:template> 
+0

Gute Antwort, +1. –

0

zu Fügen Sie die gute Antwort von @Alejandro hinzu:

Im Namen der Vollständigkeit, in XSLT man einen Schlüssel definieren könnte:

<xsl:key name="kInSubtreebyId" 
     match="item[ancestor-or-self::item[@name='x']]" 
     use="generate-id()"/> 

diesen Schlüssel und dann verweisen wie diese:

<xsl:if test="key('kInSubtreebyId', generate-id())"> 
. . . . . . . 
</xsl:if> 

In der Theorie, die Verwendung solcher Schlüssel ist möglicherweise schneller als andere Methoden, wenn der Test für einen bestimmten Knoten (im Durchschnitt) mehr als einmal ausgeführt wird.

Sie benötigen jedoch möglicherweise viel Speicher für die Indizes.

Verwandte Themen