xslt, um bereits "besuchte" Knoten zu überspringen

8

nicht sicher, ob dies möglich ist, ohne durch mehrere Pässe zu gehen, aber ich werde trotzdem fragen (mein XSL ist ein wenig eingerostet)

Ich habe ein XML-Dokument, das Knoten wie folgt enthält:

%Vor%

(Die echte Datei enthält viele Struktur-Tags, deren Abhängigkeiten nicht kreisförmig sind!)

Was ich tun möchte, ist, einen Text zu generieren (in diesem Fall C ++ struct s), und die offensichtliche Anforderung ist die Reihenfolge der struct s, also wäre meine ideale Ausgabe

%Vor%

Ich weiß, dass ich Vorwärtsdeklarationen verwenden könnte, und das würde bedeuten, dass die Reihenfolge keine Rolle spielt, das Problem ist jedoch, dass Code in den Strukturen "verarbeitet" wird und sie die tatsächliche Definition benötigen würden.

Bisher kann ich erkennen, ob ein structure irgendwelche Abhängigkeiten hat, mit dem folgenden Bit von xsl:

%Vor%

(dies geschieht in einem <xsl:template match="structure"> )

Nun, theoretisch könnte ich dann dieser Abhängigkeits-Kette folgen und die struct s für jeden Eintrag zuerst generieren, dann die, in der ich mich gerade befinde, aber wie du dir vorstellen kannst, erzeugt dies viele Kopien von gleiche Struktur - was ein Schmerz ist ..

Gibt es überhaupt eine Möglichkeit, die Kopien zu vermeiden? Grundsätzlich, sobald eine Struktur besucht wurde, und wenn wir wieder besuchen, nicht die Ausgabe des Codes dafür zu tun ... Ich brauche nicht die volle xslt, um dies zu tun (es sei denn, es ist trivial!), Sondern nur irgendwelche Ideen auf Ansätze ...

Wenn nicht, könnte ich theoretisch struct mit einem #ifdef / #define / #endif schützen, so dass der Compiler nur die erste Definition verwendet, aber das ist WIRKLICH GEFÄHRLICH! : (

(NOTES: xslt 1.0, xsltproc unter Linux: libxml 20623, libxslt 10115 und libexslt 812)

    
Nim 17.11.2010, 15:18
quelle

3 Antworten

7

Diese Umwandlung :

%Vor%

bei Anwendung auf das bereitgestellte XML-Dokument :

%Vor%

erzeugt das gewünschte, korrekte Ergebnis :

%Vor%

Erläuterung : structure Elemente werden streng nacheinander verarbeitet. Zu jeder Zeit verarbeiten wir das erste structure -Element, dessen id noch nicht im Parameter pVisited registriert ist und keinen field/@idref -Wert hat, der nicht bereits im Parameter pVisited ist und auf ein existierendes verweist structure element.

    
Dimitre Novatchev 17.11.2010, 17:44
quelle
3

Nur zum Spaß, anderen Ansatz (Level für Level) und ussing Tasten:

%Vor%

Ausgabe:

%Vor%     
user357812 17.11.2010 20:45
quelle
2

Ooh, das ist komplizierter als es zuerst aussieht. +1 für eine gute Frage.

Ich denke, der beste Weg, dies in XSLT 1.0 zu erreichen, besteht darin, einen akkumulierenden Parameter zu übergeben, wenn Sie Vorlagen auf eine Struktur anwenden. Der Parameter (nennen wir ihn "$ besucht-Strukturen") ist eine durch Leerzeichen getrennte Liste von Namen von Strukturen, die Sie bereits verarbeitet haben.

Update: Endlich bekommen. : -)

Überprüfen Sie in der Vorlage für die Verarbeitung einer Struktur, ob andere Strukturen, von denen diese abhängig ist, nicht bereits in $ visited-structures aufgeführt sind. Ist dies nicht der Fall, generieren Sie den Code für diese Struktur, und untersuchen Sie die Vorlage, indem Sie die nächste nicht besuchte Struktur auswählen und den aktuellen Strukturnamen an den Parameter $ visited-structures anhängen. Andernfalls generieren Sie keinen Code für die Struktur, sondern rekursieren Sie die Vorlage, indem Sie die erste Abhängigkeitsstruktur auswählen und den Parameter $ visited-structures unverändert übergeben.

Hier ist der Code ...

%Vor%

Und die Ausgabe:

%Vor%     
LarsH 17.11.2010 16:44
quelle

Tags und Links