xpath - XSLT 2.0: How to replace() part of an element's value and use the result in a select operation? -
i've done bit of xpath in c++ , c# applications, first time using directly in xslt. have xml file formatted this:
<toplevel> <foo> <bar>prefix1_taxi</bar> ... </foo> <foo> <bar>prefix1_schoolbus</bar> ... </foo> ... <foo> <bar>prefix2_taxi</bar> ... </foo> <foo> <bar>prefix2_schoolbus</bar> ... </foo> </toplevel>
first, want select <foo>
elements have <bar>
element starts "prefix1_." appears work:
<xsl:for-each select="foo[bar[starts-with(., 'prefix1_')]]"> <!-- style , format values child elements of "prefix1_" <foo> --> </xsl:for-each>
from inside for-each
block, want select <foo>
element contains corresponding "prefix2_" element. want pull data out of each see fit.
for example, when for-each
has selected "prefix1_taxi", want select foo
element contains "prefix2_taxi" bar
element.
<xsl:for-each select="foo[bar[starts-with(., 'prefix1_')]]"> <!-- retrieve corresponding "prefix2_" foo --> <!-- style , format values child elements of "prefix1_" <foo> --> <!-- style , format values child elements of "prefix2_" <foo> --> </xsl:for-each>
unfortunately, have no idea how go this. in traditional program following pseudocode:
string buf = barelement.name.replace("prefix1_", string.empty); xmlnode otherfoo = document.selectsinglenode("foo[bar[" + buf + "]]");
however xslt works different paradigm retrieving values , manipulating data, i'm trying break out of old mode of thinking.
using i've gathered googling on xslt, came pretty ugly:
select foo element containing bar starts text:
foo[bar[starts-with(., ...)
replace "prefix1_" in our current
<bar>
element:replace(<xsl:value-of select='bar'/>, 'prefix1_', '')
this yields pretty ugly mess:
<xsl:value-of select="foo[bar[starts-with(., replace(<xsl:value-of select='bar'/>, 'prefix1_', ''))]]" />
i'm pretty sure <xsl:value-of>
element isn't correct.
how go this? suspect i'm missing core concepts of how express concept in xslt. i'm slogging through w3.org page on xslt still need much more study , practice.
this xsl stylesheet should give flexibility foo
elements contain "prefix2".
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform"> <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/> <xsl:strip-space elements="*"/> <!-- matches top level element , selects children prefix1 text. --> <xsl:template match="toplevel"> <xsl:copy> <xsl:apply-templates select="foo[bar[starts-with(., 'prefix1_')]]"/> </xsl:copy> </xsl:template> <!-- we're @ foo element prefix1 text. select siblings of same vehicle type, prefix2 text. --> <xsl:template match="foo[bar[starts-with(., 'prefix1_')]]"> <xsl:variable name="vehicle" select="substring-after(bar, 'prefix1_')"/> <xsl:apply-templates select="../foo[bar = concat('prefix2_', $vehicle)]"/> </xsl:template> <!-- in template, can whatever want foo element containing prefix2 vehicles. example copies element , children. --> <xsl:template match="foo[bar[starts-with(., 'prefix2_')]]"> <xsl:copy-of select="."/> </xsl:template> </xsl:stylesheet>
Comments
Post a Comment