Subject: [xsl] Comparing direct ancestors From: Spencer Tickner <spencertickner@xxxxxxxxx> Date: Thu, 24 May 2012 08:40:05 -0700 |
Hi List, Thanks in advance for any help. I've been banging my head around this problem for awhile now and could use any advice anyone is willing to give. I have the following xml: <?xml version="1.0"?> <root> <change-begin/> <a> <p>Foo<change-end/></p> </a> <change-begin/> <b> <d> <t>Bar</t> </d> <d> <t>Foo</t> </d> </b> <change-end/> <p>Nothing <change-begin/>to worry<change-end/> about</p> </root> I need to write an xslt (2.0 is fine) that will "move" the <change-begin/> and <change-end/> elements to be children of the nearest pre-defined allowable element. So in the example above I have <p> and <t> as elements that allow the <change-begin/> and <change-end/> elements. The output should look like this: <?xml version="1.0"?> <root> <a> <p><change-begin/>Foo<change-end/></p> </a> <b> <d> <t><change-begin/>Bar</t> </d> <d> <t>Foo<change-end/></t> </d> </b> <p>Nothing <change-begin/>to worry<change-end/> about</p> </root> My plan was a multi-pass stylesheet that first took care of the <change-begin/> then went on to take care of the <change-ends/>. For brevity I've limit this post to trying to deal with the <change-begin/>: <?xml version='1.0'?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:variable name="allowed"> <n>p</n> <n>t</n> </xsl:variable> <xsl:template match="/"> <xsl:apply-templates select="root" mode="begins"/> </xsl:template> <xsl:template match="*" mode="begins"> <xsl:variable name="name" select="name()"/> <!-- ok here we narrow our field of vision --> <xsl:choose> <!-- Only worry about elements that are possible candidates for moving changes in --> <xsl:when test="$allowed/n[name() = $name]"> <xsl:choose> <!-- Is a sibiling a change-begin tag, or are any ancestors siblings a change-begin tag? --> <xsl:when test="preceding-sibling::change-begin or (ancestor::*[preceding-sibling::change-begin])"> <xsl:copy> <change-begin/> <xsl:copy-of select="@*"/> <xsl:apply-templates mode="begins"/> </xsl:copy> </xsl:when> <xsl:otherwise> <xsl:copy> <xsl:copy-of select="@*"/> <xsl:apply-templates mode="begins"/> </xsl:copy> </xsl:otherwise> </xsl:choose> </xsl:when> <xsl:otherwise> <xsl:copy> <xsl:copy-of select="@*"/> <xsl:apply-templates mode="begins"/> </xsl:copy> </xsl:otherwise> </xsl:choose> </xsl:template> <!-- remove the begins outside of allowable elements. --> <xsl:template match="change-begin" mode="begins"> <xsl:if test="parent::*[name() = $allowed/n/.]"> <xsl:copy> <xsl:copy-of select="@*"/> <xsl:apply-templates mode="begins"/> </xsl:copy> </xsl:if> </xsl:template> </xsl:stylesheet> So far it doesn't work and is fast becoming a bunch of spaghetti <choose> statements. If anyone has any ideas I would love to hear them. Thanks
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] RE: Diagram of XPath axes, Syd Bauman | Thread | Re: [xsl] Comparing direct ancestor, David Carlisle |
Re: [xsl] Diagram of XPath axes, G. Ken Holman | Date | Re: [xsl] Comparing direct ancestor, David Carlisle |
Month |