Pairing Elements XSLT
Here should go questions about transforming XML with XSLT and FOP.
-
- Posts: 5
- Joined: Tue Mar 04, 2008 5:07 am
Pairing Elements XSLT
Hi,
I'm trying to write a transformation that takes repeating elements and places them in pairs and in order in the XML output. I want to convert this:
into:
My current XSLT finds each element and pairs it with its following-sibling but because it processes each node I get a
<double_module><para>Para 1</para><para>Para 2</para></double_module> and a <double_module><para>Para 2</para><para>Para 3</para></double_module>
Any assistance is greatly appreciated.
Thanks,
Bay
I'm trying to write a transformation that takes repeating elements and places them in pairs and in order in the XML output. I want to convert this:
Code: Select all
<Root>
<heading>Chapter 1</heading>
<module>
<para>Para 1</para>
</module>
<module>
<para>Para 2</para>
</module>
<module>
<para>Para 3</para>
</module>
<module>
<para>Para 4</para>
</module>
<module>
<para>Para 5</para>
</module>
<heading>Chapter 2</heading>
<module>
<para>Para 6</para>
</module>
<module>
<para>Para 7</para>
</module>
<module>
<para>Para 8</para>
</module>
</Root>
Code: Select all
<Root>
<heading>Chapter 1</heading>
<double_module>
<para>Para 1</para>
<para>Para 2</para>
</double_module>
<double_module>
<para>Para 3</para>
<para>Para 4</para>
</double_module>
<module>
<para>Para 5</para>
</module>
<heading>Chapter 2</heading>
<double_module>
<para>Para 6</para>
<para>Para 7</para>
</double_module>
<module>
<para>Para 8</para>
</module>
<heading>Chapter 3</heading>
</Root>
<double_module><para>Para 1</para><para>Para 2</para></double_module> and a <double_module><para>Para 2</para><para>Para 3</para></double_module>
Code: Select all
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output indent="yes"/>
<xsl:template match="Root">
<lesson>
<xsl:apply-templates/>
</lesson>
</xsl:template>
<xsl:template match="para">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="heading">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="module">
<xsl:choose>
<xsl:when test="following-sibling::*[1][self::module]"> <double_module>
<xsl:apply-templates/>
<xsl:apply-templates mode="in-module"
select="following-sibling::*[1][self::module]"/>
</double_module>
</xsl:when>
<xsl:otherwise>
<module>
<xsl:apply-templates/>
</module>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="module" mode="in-module">
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
Thanks,
Bay
-
- Posts: 5
- Joined: Tue Mar 04, 2008 5:07 am
Re: Pairing Elements XSLT
Thanks!
I assume you meant:
... which just about works.
The problem now is that module 6 (where position() mod 2 = 0)which follows a <chapter> should begin a <double_ module>, but instead is ignored by the above template.
I assume you meant:
Code: Select all
<xsl:template match="module[position() mod 2 = 0]"/>
The problem now is that module 6 (where position() mod 2 = 0)which follows a <chapter> should begin a <double_ module>, but instead is ignored by the above template.
-
- Site Admin
- Posts: 2095
- Joined: Thu Jan 09, 2003 2:58 pm
Re: Pairing Elements XSLT
Hi,
My approach will be with a positional processing. Match on the Root and apply templates on the first element. For heading and modules that do not have a pair just copy them and process the next sibling. The other modules will have a pair so when we match on one we copy the content of that and the content of the following module inside a double-module element.
Best Regards,
George
My approach will be with a positional processing. Match on the Root and apply templates on the first element. For heading and modules that do not have a pair just copy them and process the next sibling. The other modules will have a pair so when we match on one we copy the content of that and the content of the following module inside a double-module element.
Code: Select all
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:template match="Root">
<xsl:copy>
<xsl:apply-templates select="*[1]"/>
</xsl:copy>
</xsl:template>
<xsl:template
match="heading|module[following-sibling::*[1][self::heading] or
not(following-sibling::*)]">
<xsl:copy-of select="."/>
<xsl:apply-templates select="following-sibling::*[1]"/>
</xsl:template>
<xsl:template match="module">
<double-module>
<xsl:copy-of select="./*"/>
<xsl:copy-of select="following-sibling::*[1]/*"/>
</double-module>
<xsl:apply-templates select="following-sibling::*[2]"/>
</xsl:template>
</xsl:stylesheet>
George
George Cristian Bina
Jump to
- Oxygen XML Editor/Author/Developer
- ↳ Feature Request
- ↳ Common Problems
- ↳ DITA (Editing and Publishing DITA Content)
- ↳ SDK-API, Frameworks - Document Types
- ↳ DocBook
- ↳ TEI
- ↳ XHTML
- ↳ Other Issues
- Oxygen XML Web Author
- ↳ Feature Request
- ↳ Common Problems
- Oxygen Content Fusion
- ↳ Feature Request
- ↳ Common Problems
- Oxygen JSON Editor
- ↳ Feature Request
- ↳ Common Problems
- Oxygen PDF Chemistry
- ↳ Feature Request
- ↳ Common Problems
- Oxygen Feedback
- ↳ Feature Request
- ↳ Common Problems
- Oxygen XML WebHelp
- ↳ Feature Request
- ↳ Common Problems
- XML
- ↳ General XML Questions
- ↳ XSLT and FOP
- ↳ XML Schemas
- ↳ XQuery
- NVDL
- ↳ General NVDL Issues
- ↳ oNVDL Related Issues
- XML Services Market
- ↳ Offer a Service