Reputation: 35
Need to transform XML structure mentioned below using XSLT 2.0 or 3.0,
from
<RD>
<RE>
<BI>B00</BI>
<BI>B01</BI>
<BI>B02</BI>
<BI>B03</BI>
<CI>C01</CI>
<D>D01</D>
</RE>
<RE>
<BI>B04</BI>
<BI>B05</BI>
<CI>C02</CI>
<D>D02</D>
</RE>
</RD>
to this:
<RD>
<RE>
<BI>B00</BI>
<CI>C01</CI>
<D>D01</D>
</RE>
<RE>
<BI>B01</BI>
<CI>C01</CI>
<D>D01</DI>
</RE>
<RE>
<BI>B02</BI>
<CI>C01</CI>
<D>D01</D>
</RE>
<RE>
<BI>B03</BI>
<CI>C01</CI>
<D>D01</D>
</RE>
<RE>
<BI>B04</BI>
<CI>C02</CI>
<D>D02</D>
</RE>
<RE>
<BI>B05</BI>
<CI>C02</CI>
<D>D02</D>
</RE>
</RD>
Explanation: I need to achieve the distribution of XML nodes of (CI),(D) to each of (BI) tags in every iteration of (RE) tag
Upvotes: 1
Views: 61
Reputation: 167696
You can treat it as a grouping problem:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
expand-text="yes">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="RD">
<xsl:copy>
<xsl:for-each-group select="RE" group-by="BI">
<xsl:copy>
<BI>{current-grouping-key()}</BI>
<xsl:apply-templates select="*[not(self::BI)]"/>
</xsl:copy>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
<xsl:mode on-no-match="shallow-copy"/>
</xsl:stylesheet>
Upvotes: 1
Reputation: 66783
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output indent="yes"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="RE">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="BI">
<RE>
<xsl:copy-of select="."/>
<xsl:copy-of select="following-sibling::*[not(self::BI)]"/>
</RE>
</xsl:template>
</xsl:stylesheet>
Upvotes: 0
Reputation: 2714
This could also have been solved simply like this :
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="RD">
<xsl:copy>
<xsl:apply-templates select="RE/BI"/>
</xsl:copy>
</xsl:template>
<xsl:template match="BI">
<RE>
<xsl:copy-of select="."/>
<xsl:copy-of select="following-sibling::CI"/>
<xsl:copy-of select="following-sibling::D"/>
</RE>
</xsl:template>
</xsl:stylesheet>
See it working here : https://xsltfiddle.liberty-development.net/gVK6D4y
Upvotes: 0