xslt - Is it possible to make xsl:template sensitive to the pushed-from node without using xsl:param? -
i'm pretty sure answer no, since alternative deem inelegant code, thought i'd throw out , see if i'm missing while hoping hasn't been asked.
given source xml:
<root> <p>hello world</p> <move elem="content" item="test"/> <p>another text node.</p> <content item="test">i can't <b>figure</b> out.</content> </root>
i want result:
<root> <block>hello world</block> <newcontent>i can't <hmmm>figure</hmmm> out.</newcontent> <block>another text node.</block> </root>
an ordinary language description:
- replace <move .../> result of processing element name matches move's @elem attribute , @item matches move's @item attribute (e.g., in case content of element [<content>] processed <b> replaced <hmm>).
- prevent element step 1 being written out result tree in original document order
the problem input xml document considerably more complex , variable. , stylesheet third-party transform extending. template i'd have copy in order use mode-based solution pretty significant in size , seems inelegant me. know, example, work:
<xsl:template match="b"> <hmmm> <xsl:apply-templates/> </hmmm> </xsl:template> <xsl:template match="p"> <block> <xsl:apply-templates/> </block> </xsl:template> <xsl:template match="move"> <xsl:variable name="elem" select="@elem"/> <xsl:variable name="item" select="@item"/> <xsl:apply-templates select="//*[name()=$elem , @item=$item]" mode="copy-and-process"/> </xsl:template> <xsl:template match="content"/> <xsl:template match="content" mode="copy-and-process"> <newcontent><xsl:apply-templates/></newcontent> </xsl:template>
what have <xsl:template> matches "content" sensitive node pushes it. so, can have <xsl:template match="content"/> executed (and therefore matching node , children suppressed) when node pushed <root> , not <move>. virtue in if third-party stylesheet's relevant template updated, don't have worry updating copy of stylesheet processes <content> node. i'm pretty sure isn't possible, thought worth asking about.
simply do:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:key name="kmover" match="move" use="concat(@elem,'+',@item)"/> <xsl:key name="ktomove" match="*" use="concat(name(),'+',@item)"/> <xsl:strip-space elements="*"/> <xsl:template match="node()|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> <xsl:template match="move"> <newcontent> <xsl:apply-templates mode="move" select= "key('ktomove', concat(@elem,'+',@item))/node()"/> </newcontent> </xsl:template> <xsl:template match="p"> <block><xsl:apply-templates/></block> </xsl:template> <xsl:template match="b" mode="move"> <hmmm><xsl:apply-templates/></hmmm> </xsl:template> <xsl:template match="*[key('kmover', concat(name(),'+',@item))]"/> </xsl:stylesheet>
when transformation applied on provided xml document:
<root> <p>hello world</p> <move elem="content" item="test"/> <p>another text node.</p> <content item="test">i can't <b>figure</b> out.</content> </root>
the wanted, correct result produced:
<root> <block>hello world</block> <newcontent>i can't <hmmm>figure</hmmm> out.</newcontent> <block>another text node.</block> </root>
Comments
Post a Comment