Reputation: 403
I have the following structure. That is to say - I may have the following structure.
The output comes from a CMS and very often there is text in front of a table and after a table. In order to make the second stage in the transformation work, wrapping the the paragraph before the table and after the table inside an element is essential.
<?xml version="1.0" encoding="UTF-8"?>
<div>
<p>some text here</p>
<p>and maybe some text here. it may or may not be here</p>
<figure>
<table>
<tbody>
<tr>
<td>test</td>
</tr>
</tbody>
</table>
</figure>
<p>Likely to be a paragraph here</p>
<p>And here - often like: table 2, but nothing I can use</p>
<figure>
<table>
<tbody>
<tr>
<td>test</td>
</tr>
</tbody>
</table>
</figure>
<p>and another paragraph at the end of the table</p>
</div>
My goal is to get an output like below where the first paragraph in the beginning has it's own wrapper. then the combination of paragraph + table + paragraph is put inside a wrapper.
There might be some paragraphs at the end of the file and those should be wrapped as well.
<?xml version="1.0" encoding="UTF-8"?>
<body>
<div>
<p>some text here</p>
</div>
<div class="table">
<p>and maybe some text here. it may or may not be here</p>
<figure>
<table>
<tbody>
<tr>
<td>test</td>
</tr>
</tbody>
</table>
</figure>
<p>Likely to be a paragraph here</p>
</div>
<div class="table">
<p>And here - often like: table 2, but nothing I can use</p>
<figure>
<table>
<tbody>
<tr>
<td>test</td>
</tr>
</tbody>
</table>
</figure>
<p>another text at the end of the table</p>
</div>
</body>
I am playing around with preceding and following + parent. Any pointers in the right direction would be of great help
I am restricted to XSLT 1.0.
Upvotes: 0
Views: 37
Reputation: 116992
I don't think the problem is well-defined. Given certain assumptions (which should be self-evident), and given a well-formed input such as:
XML
<body>
<p>some text here</p>
<p>and maybe some text here. it may or may not be here</p>
<figure>
<table>
<tbody>
<tr>
<td>test</td>
</tr>
</tbody>
</table>
</figure>
<p>Likely to be a paragraph here</p>
<p>And here - often like: table 2, but nothing I can use</p>
<figure>
<table>
<tbody>
<tr>
<td>test</td>
</tr>
</tbody>
</table>
</figure>
<p>and another paragraph at the end of the table</p>
</body>
you could do something like:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="body">
<xsl:copy>
<xsl:apply-templates select="p[not(preceding-sibling::*[1][self::figure] or following-sibling::*[1][self::figure])]" mode="stand-alone"/>
<xsl:for-each select="figure">
<div class="table">
<xsl:copy-of select="preceding-sibling::*[1][self::p]"/>
<xsl:copy-of select="."/>
<xsl:copy-of select="following-sibling::*[1][self::p]"/>
</div>
</xsl:for-each>
</xsl:copy>
</xsl:template>
<xsl:template match="p" mode="stand-alone">
<div>
<xsl:copy-of select="."/>
</div>
</xsl:template>
</xsl:stylesheet>
to get:
Result
<body>
<div>
<p>some text here</p>
</div>
<div class="table">
<p>and maybe some text here. it may or may not be here</p>
<figure>
<table>
<tbody>
<tr>
<td>test</td>
</tr>
</tbody>
</table>
</figure>
<p>Likely to be a paragraph here</p>
</div>
<div class="table">
<p>And here - often like: table 2, but nothing I can use</p>
<figure>
<table>
<tbody>
<tr>
<td>test</td>
</tr>
</tbody>
</table>
</figure>
<p>and another paragraph at the end of the table</p>
</div>
</body>
Upvotes: 1