XSLT / XPATH: Auswählen eines vorhergehenden Kommentars
-
18-09-2019 - |
Frage
Ich habe XML im folgenden Format, das ich neu formatieren möchte:
<blocks>
<!-- === apples === -->
<block name="block1">
...
</block>
<!-- === bananas === -->
<block name="block2">
...
</block>
<!-- === oranges === -->
<block name="block3">
...
</block>
</blocks>
Mein Problem ist, dass ich nicht herausfinden kann, wie ich die Kommentare oben jedes Block -Tags auswählen soll. Ich habe das folgende XSL:
<xsl:template match="//blocks">
<xsl:apply-templates select="block" />
</xsl:template>
<xsl:template match="block">
<xsl:apply-templates select="../comment()[following-sibling::block[@name = ./@name]]" />
<xsl:value-of select="./@name" />
</xsl:template>
<xsl:template match="comment()[following-sibling::block]">
<xsl:value-of select="."></xsl:value-of>
</xsl:template>
Die Ausgabe, für die ich versuche, ist:
=== apples ===
Block 1
=== Bananen ===
Block2
=== Orangen ===
Block3
Aber das Beste, was ich bekommen kann, ist:
=== apples ===
=== Bananen ===
=== Orangen ===
Block 1
=== apples ===
=== Bananen ===
=== Orangen ===
Block2
=== apples ===
=== Bananen ===
=== Orangen ===
Block3
Ich benutze PHP, wenn das einen Unterschied macht.
Lösung
Sie können die Vorlagen für Kommentare auch in Ihren ersten Antrags -Templates anstelle der zweiten anwenden, sodass dies in der Reihenfolge geschieht. Außerdem hängt diese Lösung von der Reihenfolge der Daten in der Quelle XML ab.
<xsl:template match="//blocks">
<xsl:apply-templates select="block | comment()" />
</xsl:template>
PS:- Sie können es vermeiden, "//" in Ihren Ausdrücken zu verwenden, da es nicht optimal sein kann.
BEARBEITEN Komplettes Stylesheet
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="//blocks">
<xsl:apply-templates select="block | comment()"/>
</xsl:template>
<xsl:template match="block">
<xsl:value-of select="./@name"/>
</xsl:template>
<xsl:template match="comment()">
<xsl:value-of select="."/>
</xsl:template>
</xsl:stylesheet>
Fügen Sie die folgende Anweisung hinzu, wenn Sie Newlines möchten, nachdem Sie den Wert sowohl im Block als auch im Kommentar gedruckt haben.
<xsl:text> </xsl:text>
Andere Tipps
Ihr Stylesheet ist etwas übermäßig kompliziert.
Sie sollten das Stylesheet unten ausprobieren und werden feststellen, dass es der gewünschten Ausgabe entspricht!
<xsl:template match="//blocks">
<xsl:apply-templates select="block" />
</xsl:template>
<xsl:template match="block">
<xsl:apply-templates select="preceding-sibling::comment()[1]" />
<xsl:value-of select="./@name" />
</xsl:template>
<xsl:template match="comment()">
<xsl:value-of select="."></xsl:value-of>
</xsl:template>
Dieser Code stimmt immer mit 1 oder 0 Kommentaren überein, die kurz vor dem aktuellen Block -Tag beginnen.