How to remove text | xslt - xslt

Output data:
<sku>SKU 11077</sku>
XSLT
<xsl:element name="sku">
V31L-<xsl:value-of select="sku"/>
</xsl:element>
I try to remove SKU and SPACE to get result:
<sku>V31L-11077</sku>

Xslt has the substring-after function, that you can use like this:
<xsl:element name="sku">
<xsl:text>V31L-</xsl:text>
<xsl:value-of select="substring-after(sku,'SKU ')"/>
</xsl:element>

Related

How get first name initial and last name in XSLT

I want yo get the first name initial and last name.
Input :
<root>
<ele name="Samp Huwani"/>
<ele name="Gong Gitry"/>
<ele name="Dery Wertnu"/>
</root>
Output
<names>S Huwani</name>
<names>G Gitry</name>
<names>D Wertnu</name>
Tried Code:
<xsl:template match="root/name">
<names>
<xsl:value-of select="#name" />
</name>
</xsl:template>
I am using XSLT 2.0 . Thank you
With the given example, you could use:
<xsl:template match="/root">
<xsl:copy>
<xsl:for-each select="ele">
<name>
<xsl:value-of select="substring(#name, 1, 1)"/>
<xsl:text> </xsl:text>
<xsl:value-of select="substring-after(#name, ' ')"/>
</name>
</xsl:for-each>
</xsl:copy>
</xsl:template>
However, names often do not conform to the same pattern.
In XSLT 2.0, you could simplify(?) this by using regex, e.g.:
<xsl:value-of select="replace(#name, '^(.{1}).* (.*)', '$1 $2')"/>

Partially rename an XML node

Given the XML snippet:
<rng:define name="starting_limits">
<rng:element name="limits">
<rng:ref name="Limits"/>
</rng:element>
</rng:define>
I want this:
<rng:define name="limits">
<rng:element name="limits">
<rng:ref name="Limits"/>
</rng:element>
</rng:define>
For all define elements. So I just want to remove the "starting_" prefix for all define element name attributes in the infoset.
you can use this:
<xsl:template match="#*[starts-with(., 'starting_')]">
<xsl:attribute name="{name()}" select="replace(., 'starting_', '')"/>
</xsl:template>
it matched all attribute start-with 'starting_' and remove it from output
In your XML the attribute is called name and has a value of starting_xxxx, so to match it, you would do this...
<xsl:template match="#name[starts-with(., 'starting_')]">
Or maybe this, in XSLT 2.0 and above
<xsl:template match="#name[matches(., 'starting_.*')]">
To remove the starting_attribute you can do one of the following, for example
<xsl:value-of select="substring-after(., 'starting_')"/>
<xsl:value-of select="substring(., 10)"/>
So, for example, your template may look like this
<xsl:template match="#name[starts-with(., 'starting_')]">
<xsl:attribute name="name">
<xsl:value-of select="substring(., 10)"/>
</xsl:attribute>
</xsl:template>
If you wanted to make it more generic, and match any attribute, not just one called name, you could change it to this
<xsl:template match="#*[starts-with(., 'starting_')]">
<xsl:attribute name="{name()}">
<xsl:value-of select="substring(., 10)"/>
</xsl:attribute>
</xsl:template>

Seperate attribute values with comma in xslt 1.0?

My source XML:-
<wireframe:xaIDExclusion>
<widget:xaID id="12"/>
<widget:xaID id="121"/>
<widget:xaID id="123"/>
<widget:xaID id="124"/>
<widget:xaID id="3456"/>
</wireframe:xaIDExclusion>
This is what i tried
<xsl:template match="widget:xaID">
<xsl:element name="xaid">
<xsl:variable name ="value" select="#id"></xsl:variable>
<xsl:value-of select="concat($value,',')"></xsl:value-of>
</xsl:element>
</xsl:template>
I need output like this,how to do that
12,121,123,124,3456
Thanks in advance
The problem with your approach is that you're matching widget:xaID and then creating a xaid element; this results in multiple xaid elements, one for each widget:xaID. You need to create the xaid element while you are in the context of the parent of widget:xaID.
Try (untested, because you did not provide a well-formed XML):
<xsl:template match="wireframe:xaIDExclusion">
<xaid>
<xsl:for-each select="widget:xaID">
<xsl:value-of select="#id">
<xsl:if test="position()!=last()">, </xsl:if>
</xsl:for-each>
</xaid>
</xsl:template>

Split and concatenate a string in XSLT

Hi I have the below line in by XML and also I need a hyperlink for the number. I want this output to be shown in HTML format.
<main>
<alph>a b 2,3</alph>
</main>
I want an XSLT that gives output as:
a b 2, a b 3
I have tried the below XSLT:
<xsl:template match="alph">
<xsl:variable name="link" select="normalize-space(translate(
normalize-space(current()),abcdefghijklmnopqrstuvwxyz,''))"/>
<xsl:value-of select="substring-before(normalize-space(.),$link)"/>
<xsl:variable name="tex">
<xsl:value-of select="text()"/>
</xsl:variable>
<xsl:choose>
<xsl:when test="contains($link,',')">
<xsl:variable name="new">
<xsl:value-of select="tokenize($link,',')"/>
</xsl:variable>
<xsl:value-of select="concat($new,$tex)"/>
</xsl:when>
<xsl:when test="contains($link,'-')">
<xsl:value-of select="tokenize($link,'-')"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$link"/>
</xsl:otherwise>
</xsl:choose>
But it is giving me output as:
a b 2 3a b 2,3
Thanks
One problem you have is with the variable link
<xsl:variable name="link" select="normalize-space(translate(
normalize-space(current()),abcdefghijklmnopqrstuvwxyz,''))"/>
It looks like you are trying removing all alphabetic characters from the string, so that you are left with just 2,3. However, for this to work the abc...xyz needs to be enclosed in apostrophes, otherwise it will be looking for an element named abc...xyz. Having said that, you say you are using XSLT2.0, so you can make use of the replace function here, which takes a regular expression as a parameter
<xsl:variable name="link" select="normalize-space(replace(current(),'[a-z]',''))"/>
Next, you can get the text before this link, like so
<xsl:variable name="text" select="normalize-space(substring-before(current(), $link))"/>
This will give you your a b
Finally, you can use the tokenize function to split up the 2,3. In your XSLT you seem to be looking for hyphens too, but the tokenize function also uses regular expressions, so this is not a problem. What you can do is just tokenize the string, and re-join it using the text variable as a separator
<xsl:value-of select="concat($text, ' ')"/>
<xsl:value-of select="tokenize($link,',|-')" separator="{concat(', ', $text, ' ')}"/>
Here is the full XSLT
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="alph">
<xsl:variable name="link" select="normalize-space(replace(current(),'[a-z]',''))"/>
<xsl:variable name="text" select="normalize-space(substring-before(current(), $link))"/>
<xsl:value-of select="concat($text, ' ')"/>
<xsl:value-of select="tokenize($link,',|-')" separator="{concat(', ', $text, ' ')}"/>
</xsl:template>
</xsl:stylesheet>
When applied on your XML, the following is output
a b 2, a b 3

xslt concat with select inside for-each

Can i use a Select within a concat in xslt?
eg
<xsl:for-each select="root/OrderItems/lineitem">
<xsl:element name="img">
<xsl:attribute name="src">
<xsl:value-of select="concat('http://www.site.com/r&h=11', '&q=',<xsl:value-of select="Quantity" />, )" />
</xsl:attribute>
</xsl:element>
</xsl:for-each>
Try this:
<xsl:for-each select="root/OrderItems/lineitem">
<xsl:element name="img">
<xsl:attribute name="src">
<xsl:value-of
select="concat('http://www.site.com/r&h=11', '&q=', Quantity)" />
</xsl:attribute>
</xsl:element>
</xsl:for-each>
No, because it is not well formed XML, you cannot put a self closing XML element within a self closing XML element, or I suppose in this case you cannot use an XML element in the value of an XML attribute