Frage

I am looking to fix some XML that has block level elements in paragraph tags. The XML is something like:

<p>
   This is some text with <tag>some other markup</tag> in it that also needs transformation
   <div>
     Oh no here is a block element
   </div>
   It is even worse as <i>there is more content</i> between that needs transform
   <div>
     more block content
   </div>
   more text
</p>

So the pattern is arbitrary text and nodes with mixed in block level elements. It can be any number of these divs and other text in here so answers using indexes won't work for all cases.

I am wishing to transform this to

 <p>This is some text with <transformed-tag>some other markup</transformed-tag> in it that also needs transformation</p>
 <div>Oh no here is a block element</div>
 <p>It is even worse as <i>there is more content</i> between that needs transform</p>
 <div>more block content</div>
 <p>more text</p>

So essentially I want to capture all descendants of p that are not in the div tag and wrap each with p tags while preserving the order of the text and the divs. I have tried everything but am not certain how to capture the text between the divs. I have been able to transform the data from the first blob to the first div and then the data from the last div to the end using

<xsl:template match="p[following::div]">
   <p><xsl:apply-templates/></p>
</xsl:template>


<xsl:template match="p[preceding::div]">
   <p><xsl:apply-templates/></p>
</xsl:template>

Update: Made output match. The text that is being outputted in the divs and p tags needs to have templates applied to it too as there can be elements nested in there that need style applied to them.

War es hilfreich?

Lösung

Ok, so what am I missing here?

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/p">
    <root>
        <xsl:apply-templates select="node()[1]" mode="first"/>
        <xsl:apply-templates select="div[1]"/>
    </root>
</xsl:template>

<xsl:template match="node()" mode="first">
    <p>
        <xsl:copy/>
        <xsl:apply-templates select="following-sibling::node()[1][not(self::div)]" mode="next"/>
    </p>
</xsl:template>

<xsl:template match="node()" mode="next">
    <xsl:copy>
        <xsl:apply-templates/>
    </xsl:copy>
    <xsl:apply-templates select="following-sibling::node()[1][not(self::div)]" mode="next"/>
</xsl:template>

<xsl:template match="tag" mode="next">
    <transformed-tag>
        <xsl:apply-templates/>
    </transformed-tag>
    <xsl:apply-templates select="following-sibling::node()[1][not(self::div)]" />
</xsl:template>

<xsl:template match="div">
    <xsl:copy-of select="."/>
    <xsl:apply-templates select="following-sibling::node()[1][not(self::div)]" mode="first"/>
    <xsl:apply-templates select="following::div[1]"/>
</xsl:template>

</xsl:stylesheet>
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top