dynamische xpath in xslt?
Habe ich folgenden Satz von Dateien:
SourceFile.xml:
<?xml version="1.0" encoding="utf-8" ?>
<Employees>
<Employee id="1">
<firstname relationship="headnote">Atif</firstname>
<lastname relationship="lname">Bashir</lastname>
<age relationship="age">32</age>
</Employee>
</Employees>
ParamerterSettings.xml
<?xml version="1.0" encoding="utf-8"?>
<Settings>
<Employee id="1">
<sourceFile>Lookup1.xml</sourceFile>
<sourceXpathfield>Employees/Employee[@id</sourceXpathfield>
<lookupXpathfield>Employees/Employee[@id='1']</lookupXpathfield>
<elementstoinsert>xyz</elementstoinsert>
</Employee>
</Settings>
Lookup.xml
<?xml version="1.0" encoding="utf-8"?>
<Employees>
<Employee id="1">
<department code="102">HR</department>
</Employee>
</Employees>
verwandeln.xsl
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0">
<xsl:include href="identity.xsl"/>
<xsl:param name="EmployeeId" select="'1,2'" />
<xsl:variable name="FileSettings" select="document('test3.xml')" />
<xsl:variable name="SuppressSetting" select="$FileSettings/Settings/Employee[@id = tokenize($EmployeeId, ',')]" />
<xsl:template match="Employee">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="publisher" />
<xsl:apply-templates select="node() except publisher"/>
<xsl:variable name="outerfile" select="document($SuppressSetting/sourceFile)"></xsl:variable>
<xsl:variable name="outerfiledetails" select="$outerfile/$SuppressSetting/lookupXpathfield"></xsl:variable>
<xsl:value-of select="$outerfiledetails"></xsl:value-of>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Die Ausgabe sollte sein:
<?xml version="1.0" encoding="utf-8" ?>
<Employees>
<Employee id="1">
<firstname relationship="headnote">Atif</firstname>
<lastname relationship="lname">Bashir</lastname>
<age relationship="age">32</age>
HR
</Employee>
</Employees>
Änderte ich die folgende Zeile in der Transformation.xsl
<xsl:variable name="outerfiledetails" select="$outerfile/$SuppressSetting/lookupXpathfield"></xsl:variable>
in
<xsl:variable name="outerfiledetails" select="$outerfile/Employees/Employee[@id='1']"></xsl:variable>
dann bin ich meine erste Ausgabe, aber ich will, dass die XPath-epression für beide SourceFile.xml
und Lookup.xml
in ParamerterSettings.xml
so dass ich schreiben kann, ein mehr Allgemeines Skript. Kann dies in irgendeiner anderen Art und Weise dann die dynamischen xpath? Jede Idee oder Hinweis zu impelement das gleiche wird sehr geschätzt werden.
Es ist ein guter Fortschritt, den Sie haben, vereinfacht Ihre erste fast monströse Frage, aber diese Frage ist noch zu Komplex und nicht klar definiert. Versuchen rephraze und vereinfachen Sie es weiter-ich bin mir sicher, dass Sie brauchen nicht alle details. Vor allem, dass die Arbeit mit mehr als zwei Dateien macht jeder aufgeben auch versucht, die Frage zu verstehen. Zu Komplex: ich würde nie ein design eines XSLT-app auf diese Weise, und glauben Sie mir, ich habe XSLT-apps wirklich herausfordernde Komplexität, dass 99% der Entwickler nicht glauben, dass Sie zu tun, mit XSLT.
Hi Dimitre, was ich will, ist zur Ausführung der xpath-Wert aus der externen Datei. Grund dafür ist, ich habe mehrere exeternal-Dateien aus denen ich Daten und einfügen der Daten zurück in die Haupt-Quellcode-Datei. Ich kann es tun, durch harte Codierung mehrere Vorlagen, aber ich möchte vermeiden, und erstellen Sie eine Vorlage, die lautet: aus mehreren Dateien, basierend auf verschiedenen joins oder xpath-Werte definieren, die als Einstellungen in einer externen Datei.
Antwort ist richtig: dies kann nicht getan werden, in XSLT/XPath 2.0, und es könnte eine nächste version. Jedoch bezweifle ich stark die Notwendigkeit von dynamischer XPath-Auswertung -- wenn du dein problem schilderst gut, es könnte eine Lösung sein, dass doesn;t brauchen. Warum spielst du nicht einfach die Frage in Ihrer einfachsten form: "Wie bewerte ich diesen Ausdruck, die in dieser XML-Dokument?". Während ein reiner XSLT-Lösung ist nicht möglich, es gibt mindestens drei verschiedene "hybride" Lösungen, die ich kenne für dieses problem.
Siehe meine Antwort für drei verschiedene Lösungen für Ihr problem, so dass Sie würde nicht warten, bis XSLT 3.0 kommt. 🙂
Hi Dimitre, was ich will, ist zur Ausführung der xpath-Wert aus der externen Datei. Grund dafür ist, ich habe mehrere exeternal-Dateien aus denen ich Daten und einfügen der Daten zurück in die Haupt-Quellcode-Datei. Ich kann es tun, durch harte Codierung mehrere Vorlagen, aber ich möchte vermeiden, und erstellen Sie eine Vorlage, die lautet: aus mehreren Dateien, basierend auf verschiedenen joins oder xpath-Werte definieren, die als Einstellungen in einer externen Datei.
Antwort ist richtig: dies kann nicht getan werden, in XSLT/XPath 2.0, und es könnte eine nächste version. Jedoch bezweifle ich stark die Notwendigkeit von dynamischer XPath-Auswertung -- wenn du dein problem schilderst gut, es könnte eine Lösung sein, dass doesn;t brauchen. Warum spielst du nicht einfach die Frage in Ihrer einfachsten form: "Wie bewerte ich diesen Ausdruck, die in dieser XML-Dokument?". Während ein reiner XSLT-Lösung ist nicht möglich, es gibt mindestens drei verschiedene "hybride" Lösungen, die ich kenne für dieses problem.
Siehe meine Antwort für drei verschiedene Lösungen für Ihr problem, so dass Sie würde nicht warten, bis XSLT 3.0 kommt. 🙂
InformationsquelleAutor atif | 2011-01-07
Du musst angemeldet sein, um einen Kommentar abzugeben.
Dynamische XPath-Auswertung nicht möglich ist, im reinen XSLT 1.0 oder 2.0.
Es gibt mindestens drei Möglichkeiten, dies zu tun in einer "hybrid" - Lösung:
I. Verwenden Sie die EXSLT-Funktion
dyn:evaluate()
Leider nur sehr wenige XSLT 1.0-Prozessoren implementieren
dyn:evaluate()
.II. Verarbeiten der XML-Dokument mit XSLT und generieren Sie eine neue XSLT-Datei enthält den XPath-Ausdrücke-dann führen Sie die neu-generierten transformation.
Sehr wenige Leute tun dies und, meiner Meinung nach, dies ist komplexer, als die nächste Lösung.
III. Der Weg die XPath Visualizer funktioniert
Die Idee ist:
Habe eine Globale variable in das XSLT-stylesheet definiert, wie diese:
Laden Sie anschließend das stylesheet als XML-Dokument mit DOM, und ersetzen Sie die
select
Attribut dervExpression
variable mit dem eigentlichen XPath-Ausdruck enthalten ist, die in der Quell-XML-Dokument.Schließlich initiieren Sie die Umgestaltung mit dem in den Speicher geladen und dynamisch aktualisiert xslt-stylesheet.
Es ist nicht allzu kompliziert-können Sie daran interessiert zu schauen, den Quellcode der XPath Visualizer-dies ist nur ein paar Zeilen code.
Hier ist ein Beispiel für den Ansatz #1: stackoverflow.com/questions/230411/...
dyn:evaluate
genial..xsltproc
implementiert, und das war alles was ich brauchte. Danke für den tollen Tipp.In XSLT 3.0 gibt es eine neue Anweisung:
<xsl:evaluate>
-- darüber Lesen Sie hier: w3.org/TR/2014/WD-xslt-30-20141002/#dynamic-xpathInformationsquelleAutor Dimitre Novatchev
Können Sie es nicht in XSLT 2.0, aber Sie werden in der Lage sein, es zu tun in der neuesten version von XSLT:
http://www.w3.org/TR/xslt-21/#element-evaluate
InformationsquelleAutor Nick Jones
Ja, wir können ... zumindest ansatzweise. Hier ist ein workaround, welches ich mit Saxon-CE (XSLT 2.0), bis die "bewerten" - Funktion verfügbar ist. Vielleicht funktioniert das nicht für alle Arten von komplexen XML-Dokumenten, aber wahrscheinlich können Sie über den "filter", wie Sie benötigen (Abfrage auf Attribute, etc.).
In meiner speziellen situation habe ich von xPath-Ausdrücken zu beschreiben, um "volle" Pfad der Elemente einschließlich Ihrer Namen und der trick ist, verwenden Sie einen Platzhalter in Kombination mit nur das Letzte element des dynamischen xPath-Ausdruck, z.B. "Dritte" statt "erste/zweite/Dritte":
Zur Begrenzung der Folge (wählen Sie alle Elemente mit dem Namen "Dritten"), müssen Sie die Abfrage auf die Ahnen "erste" und "zweite", zu. Vielleicht hat noch jemand eine Idee zum vereinfachen Sie den folgenden code, insbesondere die Berufung der Vorfahren:
Als für meine Zwecke nur das erste übereinstimmende element, das keine untergeordneten Knoten zurückgegeben. Wahrscheinlich haben Sie zu passen Sie diese Ihren Bedürfnissen an.
<xsl:choose>
ist eine gute Idee, zumindest dann, wenn die Auswahl ist relativ kurz, es löste meine Dynamik-problem in ein paar Zeilen.InformationsquelleAutor Uwe Lagler