Klar, kein Problem:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
<xsl:output indent="yes" />
<xsl:template match="/data">
<!-- copy the document element -->
<xsl:copy>
<!-- That's where we start: all "record" nodes that have no "\". -->
<xsl:apply-templates mode="recurse" select="/data/record[
not(contains(@Name, '\'))
]" />
</xsl:copy>
</xsl:template>
<xsl:template match="record" mode="recurse">
<xsl:param name="starting-path" select="''" />
<!-- The record node and its ID attribute can be copied. -->
<xsl:copy>
<xsl:copy-of select="@ID" />
<!-- Create the new "name" attribute. -->
<xsl:attribute name="Name">
<xsl:value-of select="substring-after(@Name, $starting-path)" />
</xsl:attribute>
<!-- Append a backslash to the current path. -->
<xsl:variable name="current-path" select="concat(@Name, '\')" />
<!-- Select all "record" nodes that are one level deeper... -->
<xsl:variable name="children" select="/data/record[
starts-with(@Name, $current-path)
and
not(contains(substring-after(@Name, $current-path), '\'))
]" />
<!-- ...and apply this template to them. -->
<xsl:apply-templates mode="recurse" select="$children">
<xsl:with-param name="starting-path" select="$current-path" />
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Ausgang auf meinem System:
<data>
<record ID="26" Name="category 1">
<record ID="24" Name="sub category 1">
<record ID="25" Name="sub category 2"></record>
<record ID="27" Name="sub category 3"></record>
</record>
</record>
</data>
Beachten Sie, dass die gesamte Lösung auf der Annahme beruht, dass alle Pfade kanonisch sind und enthalten keine Hinterschrägstriche .
Beachten Sie auch, dass alle nicht übereinstimmenden/verwaisten "Record" -Elemente nicht in der Ausgabe enthalten sind (es sei denn, sie befinden sich natürlich auf der Stammebene).
Noch eine Sache: Der Template-Modus ("Recurse") ist nicht unbedingt notwendig. Ich habe es eingefügt, weil die Vorlage etwas ziemlich Spezielles vornimmt und es möglicherweise die Möglichkeit gibt, dass in Ihrer Lösung eine andere Vorlage vorhanden ist, die mit "Record" -Knoten übereinstimmt. In diesem Fall kann diese Lösung hineinfallen, ohne etwas anderes zu beschädigen. Für eine eigenständige Lösung können die Vorlagenmodi jederzeit gelöscht werden.
Oh, und das letzte, was: Wenn Sie das Ergebnis Dokument nach Namen geordnet werden, umfassen ein <xsl:sort>
element mit den <xsl:apply-templates>
(beide Vorkommen), etwa so:
<xsl:apply-templates select="...">
<xsl:sort select="@Name" data-type="text" order="ascending" />
</xsl:apply-templates>
@myso: „Unterkategorie 3 "befindet sich auf derselben Ebene wie" Unterkategorie 2 "in Ihrer XML-Eingabe. Es kann nicht so verschachtelt werden, wie Sie es in Ihrer XML-Ausgabe anzeigen. – Tomalak
Ja, mein Fehler. Habe es bearbeitet. – mysomic