fistofzen Posted September 18, 2011 Share Posted September 18, 2011 I have this xml <root><p> <span> <tag>Foo</tag> <br/> </span></p><p> <span> <tag>Foo</tag> <br/> </span> <span> <tag>Foo</tag> </span> <span> <tag>Foo</tag> <br/> </span></p><p> <span> <tag>Foo</tag> </span> <span> <tag>Foo</tag> <br/> </span> <span> <tag>Foo</tag> </span> <span> <tag>Foo</tag> </span> <span> <tag>Foo</tag> <br/> </span></p></root> and I'm trying to get the following with xslt1.0 <root><p> <span> <tag>Foo</tag> </span></p><p> <span> <tag>Foo</tag> </span></p><p> <span> <tag>Foo</tag> </span> <span> <tag>Foo</tag> </span></p><p> <span> <tag>Foo</tag> </span> <span> <tag>Foo</tag> </span></p><p> <span> <tag>Foo</tag> </span> <span> <tag>Foo</tag> </span> <span> <tag>Foo</tag> </span></p></root> Here is the XSLT <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <xsl:key name="para" match="Content" use="generate-id(following-sibling::br[1])" /> <xsl:template match="p"> <xsl:apply-templates select="br" /> <xsl:if test="Content[not(following-sibling::br)]"> <p> <xsl:apply-templates select="Content[not(following-sibling::br)]" /> </p> </xsl:if> </xsl:template> <xsl:template match="br"> <p> <xsl:apply-templates select="key('para', generate-id())" /> </p> </xsl:template> <xsl:template match="span"> <span> <xsl:apply-templates select="Content" /> </span> </xsl:template> <xsl:template match="Content"> <Content> <xsl:value-of select="."/> </Content> </xsl:template></xsl:stylesheet> Which is clearly wrong for this XML but is the nearest I can get. Any help is would be greatly appreciated. Link to comment Share on other sites More sharing options...
Martin Honnen Posted September 18, 2011 Share Posted September 18, 2011 I am struggling to understand the criteria defining in which way the XML should be transformed. As all "tag" elements in the sample have the same contents "Foo" it is difficult to identify which elements in the input sample end up at which position in the result sample. And the stylesheet you have posted has stuff like match="Content" although I don't see any elements of that name in the input sample. So posting an input and desired result sample is a good way to allow us to understand what kind of transformation you want to achieve but it would help if you write some sentences as well to explain what kind of transformation you want. Link to comment Share on other sites More sharing options...
fistofzen Posted September 18, 2011 Author Share Posted September 18, 2011 Apologies for sloppyness - I want to transform all the <br/> tags into <p> tags there are three <p> tags in the original XML and I want to end up with 5. Here is the re-freshed XSL <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <xsl:key name="para" match="tag" use="generate-id(following-sibling::br[1])" /> <xsl:template match="p"> <xsl:apply-templates select="br" /> <xsl:if test="tag[not(following-sibling::br)]"> <p> <xsl:apply-templates select="tag[not(following-sibling::br)]" /> </p> </xsl:if> </xsl:template> <xsl:template match="br"> <p> <xsl:apply-templates select="key('para', generate-id())" /> </p> </xsl:template> <xsl:template match="span"> <span> <xsl:apply-templates select="Content" /> </span> </xsl:template> <xsl:template match="Content"> <Content> <xsl:value-of select="."/> </Content> </xsl:template></xsl:stylesheet> many thanks for your help Link to comment Share on other sites More sharing options...
fistofzen Posted September 18, 2011 Author Share Posted September 18, 2011 correction <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:output method="xml" indent="yes"/><xsl:key name="para" match="tag" use="generate-id(following-sibling::br[1])" /><xsl:template match="p"><xsl:apply-templates select="br" /><xsl:if test="tag[not(following-sibling::br)]"><p><xsl:apply-templates select="tag[not(following-sibling::br)]" /></p></xsl:if></xsl:template><xsl:template match="br"><p><xsl:apply-templates select="key('para', generate-id())" /></p></xsl:template><xsl:template match="span"><span><xsl:apply-templates select="tag" /></span></xsl:template><xsl:template match="tag"><tag><xsl:value-of select="."/></tag></xsl:template></xsl:stylesheet> Link to comment Share on other sites More sharing options...
Martin Honnen Posted September 18, 2011 Share Posted September 18, 2011 Here is an XSLT 1.0 sample using sibling recursion: <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="xml" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="@* | node()"> <xsl:copy> <xsl:apply-templates select="@* | node()"/> </xsl:copy> </xsl:template> <xsl:template match="p"> <xsl:apply-templates select="span[1]" mode="group"/> </xsl:template> <xsl:template match="span[not(br)]" mode="group"> <p> <xsl:apply-templates select="."/> </p> <xsl:apply-templates select="following-sibling::span[br][1]/following-sibling::span[1]" mode="group"/> </xsl:template> <xsl:template match="span[br]" mode="group"> <p> <xsl:apply-templates select="."/> </p> <xsl:apply-templates select="following-sibling::span[1]" mode="group"/> </xsl:template> <xsl:template match="span[not(br)]"> <xsl:copy> <xsl:apply-templates select="@* | node()"/> </xsl:copy> <xsl:apply-templates select="following-sibling::span[1]"/> </xsl:template> <xsl:template match="span/br"/></xsl:stylesheet> Saxon 6.5.5, when applied to the input sample <root> <p> <span> <tag>Foo 1</tag> <br/> </span> </p> <p> <span> <tag>Foo 2</tag> <br/> </span> <span> <tag>Foo 3</tag> </span> <span> <tag>Foo 4</tag> <br/> </span> </p> <p> <span> <tag>Foo 5</tag> </span> <span> <tag>Foo 6</tag> <br/> </span> <span> <tag>Foo 7</tag> </span> <span> <tag>Foo 8</tag> </span> <span> <tag>Foo 9</tag> <br/> </span> </p></root> outputs <root> <p> <span> <tag>Foo 1</tag> </span> </p> <p> <span> <tag>Foo 2</tag> </span> </p> <p> <span> <tag>Foo 3</tag> </span> <span> <tag>Foo 4</tag> </span> </p> <p> <span> <tag>Foo 5</tag> </span> <span> <tag>Foo 6</tag> </span> </p> <p> <span> <tag>Foo 7</tag> </span> <span> <tag>Foo 8</tag> </span> <span> <tag>Foo 9</tag> </span> </p></root> Link to comment Share on other sites More sharing options...
fistofzen Posted September 19, 2011 Author Share Posted September 19, 2011 Fantastic - very helpful - if I can add one small addition to the XML input. The change is at the bottom (Foo 9). I would also like to inject <p> tags in the smae way here.Many thanks for your help and time. Amazing! <root> <p> <span> <tag>Foo 1</tag> <br/> </span> </p> <p> <span> <tag>Foo 2</tag> <br/> </span> <span> <tag>Foo 3</tag> </span> <span> <tag>Foo 4</tag> <br/> </span> </p> <p> <span> <tag>Foo 5</tag> </span> <span> <tag>Foo 6</tag> <br/> </span> <span> <tag>Foo 7</tag> </span> <span> <tag>Foo 8</tag> </span> <span> <tag>Foo 9</tag> <br/> <tag>Foo 9</tag> <br/> <tag>Foo 9</tag> <br/> <tag>Foo 9</tag> </span> </p></root> Link to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.