Reputation: 23
I have the following input:
<Article>
<title>Apple</title>
<number>119.057</number>
<price>90.8</price>
<option>
<Article>
<title>Apple Green</title>
<price>144.2</price>
<number>119.086</number>
</Article>
</option>
</Article>
<Article>
<title>Coconut</title>
<number>120.882</number>
<price>10.00</price>
</Article>
<Article>
<title>Pinapple</title>
<number>120.883</number>
<price>19.00</price>
</Article>
and it should look like this:
<Article>
<title>Apple</title>
<number>119.057</number>
<price>90.8</price>
</Article>
<Article>
<title>Apple Green</title>
<price>144.2</price>
<number>119.086</number>
</Article>
<Article>
<title>Coconut</title>
<number>120.882</number>
<price>10.00</price>
</Article>
<Article>
<title>Pinapple</title>
<number>120.883</number>
<price>19.00</price>
</Article>
My Attempt so far:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" method="xml" />
<xsl:template match="root/Article">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="Article/option">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<Article>
<xsl:value-of select="*"/>
</Article>
</xsl:copy>
</xsl:template>
<!--Identity template-->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
In fact i need to remove The option-Tag and the Child-Tags should become Article-Tags. So that all nodes are on the same Level in the Tree and finally remove the option Tag.
Thanks for your Inputs!
Upvotes: 0
Views: 426
Reputation: 117140
Given a well-formed input such as:
XML
<Articles>
<Article>
<title>Apple</title>
<number>119.057</number>
<price>90.8</price>
<option>
<Article>
<title>Apple Green</title>
<price>144.2</price>
<number>119.086</number>
</Article>
</option>
</Article>
<Article>
<title>Coconut</title>
<number>120.882</number>
<price>10.00</price>
</Article>
<Article>
<title>Pinapple</title>
<number>120.883</number>
<price>19.00</price>
</Article>
</Articles>
the following stylesheet:
XSLT 1.0
<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:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Article">
<xsl:copy>
<xsl:apply-templates select="*[not(self::option)]"/>
</xsl:copy>
<xsl:apply-templates select="option"/>
</xsl:template>
<xsl:template match="option">
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
will transform an option
node from being a child of Article
to being its sibling, returning:
Result
<?xml version="1.0" encoding="UTF-8"?>
<Articles>
<Article>
<title>Apple</title>
<number>119.057</number>
<price>90.8</price>
</Article>
<Article>
<title>Apple Green</title>
<price>144.2</price>
<number>119.086</number>
</Article>
<Article>
<title>Coconut</title>
<number>120.882</number>
<price>10.00</price>
</Article>
<Article>
<title>Pinapple</title>
<number>120.883</number>
<price>19.00</price>
</Article>
</Articles>
Upvotes: 0
Reputation: 31011
You wrote: "i need to remove the options
tag and their child tags should
become (direct chilren of) Article
tag".
Then do just that, but with a minor correction: the tag you want to match
(and remove in the output) is option
(not options
).
<xsl:template match="Article/option">
<xsl:apply-templates />
</xsl:template>
Note the similarity to the identity template. The main difference is that
there is no xsl:copy
tag (which would have copied the original option
tag).
Initially I presented only the template. Below you have the full script:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" method="xml" />
<xsl:template match="Article/option">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy>
</xsl:template>
</xsl:stylesheet>
It does generate the required output.
Yet another solution. It copies only option
content, but to keep
the proper XML formatting, I added an "envelope" root (main
) tag.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" method="xml" />
<xsl:strip-space elements="*"/>
<xsl:template match="/Article">
<!-- This matches only the root Article tag, not its grandson -->
<main> <!-- You need to have a main (root) tag -->
<!-- Output only the option content -->
<xsl:apply-templates select="option"/>
</main>
</xsl:template>
<xsl:template match="option">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy>
</xsl:template>
</xsl:stylesheet>
Upvotes: 1