Bei der täglichen Entwicklung bin ich auf ein interessantes Problem gestoßen und damit die Lösung etwas bekannter wird, gibt es dazu einen neuen Beitrag. Dieses Problem tat sich im Umfeld xhtml und xsl auf. Wenn man eine xhtml Datei per xsl modifizieren will, kann es passieren, dass die Modifikation nicht greift und das verursacht gerne mal das eine oder andere graue Haar.
Zuerst aber die Ausgangssituation. Wir haben eine xhtml Datei und müssen diese weiter verarbeiten. Der Aufbau dieser Datei ist aber für die Verarbeitung ungünstig und gewisse Elemente sollen daher entfernt bzw. vereinfacht werden. Die erste Idee ist xsl zu benutzen, da man damit über XPath-Ausdrücke den DOM schnell durchsuchen und Elemente manipulieren kann.
Also benötigt man zuerst eine Identitätsregel, damit die Eingabe-xhtml-Datei zur Ausgabe-xhtml-Datei umkopiert wird. Eine solche Regel sieht bspw so aus:
<xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*" /> <xsl:apply-templates /> </xsl:copy> </xsl:template>
Nun ergänzt man Regeln, die auf bestimmte Elemente oder Elementkonstellationen reagieren. Beispielhaft entfernen wir einfach alle input
-Elemente, da wir für diese keine Verwendung haben. Möglich sind natürlich beliebige andere Regeln.
<xsl:template match="input" />
Setzt man dieses Stylesheet auf eine xhtml-Datei an, läuft man in das obige Problem. Da eine xhtml Datei üblicherweise einen Namespace hat, wird das Stylesheet nur die Identitätsregel anwenden können. Wir müssen also noch im Header des Stylesheets Modifikationen vornehmen, wie sie hier beschrieben sind.
Dadurch erhalten wir folgendes Stylesheet und dieses funktioniert dann auch wie gedacht:
<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns="http://www.w3.org/1999/xhtml" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xhtml xsl xs" > <xsl:output encoding="utf-8" method="xml"/> <xsl:template match="xhtml:input" /> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*" /> <xsl:apply-templates /> </xsl:copy> </xsl:template> </xsl:stylesheet>
Besonders zu beachten ist, das man entsprechende Namespace Prefixe in den Regeln verwenden muss. Und wie sooft gilt: Wenn man es weiß, ist es eigentlich ganz einfach.