I'm looking to get a custom attribute for anchor tag from xsl.
Is it possible to get the name of the attribute dynamically from xml?
Here is what I tried :
<xsl:attribute name="<xsl:value-of select="id"/>">
<xsl:value-of select="value"/>
</xsl:attribute>
Yes, it is possible. You can pass a variable as name value.
<xsl:variable name="attributeName" select="id"/>
<xsl:attribute name="{$attributeName}">
<xsl:value-of select="value"/>
</xsl:attribute>
You can simpify the solution from #Savard to
<xsl:attribute name="{id}">
<xsl:value-of select="value"/>
</xsl:attribute>
or if you are using XSLT 2.0, to
<xsl:attribute name="{id}" select="value"/>
Note, you can also mix-and-match dynamic and literal parts to a name:
<xsl:attribute name="{name}_example">Test</xsl:attribute>
Related
I have a variable #expectedLength. I need to assign it to a style attribute.
<xsl:if test="#expectedLength">
<xsl:attribute name="style">
<xsl:value-of select="'width:200px'"/>
</xsl:attribute>
</xsl:if>
I need to replace 200 with the value of #expectedLength. How can I use the variable?
You could change your snippet to
<xsl:if test="#expectedLength">
<xsl:attribute name="style">width: <xsl:value-of select="#expectedLength"/>;</xsl:attribute>
</xsl:if>
That should work with any version of XSLT.
In XSLT 2 and later you can also use the select expression
<xsl:if test="#expectedLength">
<xsl:attribute name="style" select="concat('width: ', #expectedLength, ';')"/>
</xsl:if>
I would prefer to and suggest to set up a template
<xsl:template match="#expectedLength">
<xsl:attribute name="style" select="concat('width: ', #expectedLength, ';')"/>
</xsl:template>
and then to make sure higher up that any attribute nodes are processed.
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>
I have an xml with img tag
<img>
source
</img>
I want to generate:
<img src="source.jpg">
I tried something like that:
<img>
<xsl:attribute name="src">
<xsl:text>
<xsl:value-of select="node()" />.jpg
</xsl:text>
</xsl:attribute>
</img>
but it doesng work
Use:
<img src="{normalize-space()}.jpg"/>
This assumes the <img> element is the current node.
The reason why what you are doing does not work is that you cannot evaluate XSLT expressions inside of the <xsl:text> element.
<xsl:text> can only contain literal text, entity references, and #PCDATA.
If you move the <xsl:value-of> outside of the <xsl:text>, then the following will work:
<img>
<xsl:attribute name="src">
<xsl:value-of select="node()" />
<xsl:text>.jpg</xsl:text>
</xsl:attribute>
</img>
However, selecting <xsl:value-of select="node()> for the <img> in your example will include the carriage returns and whitespace characters inside of the <img> element, which is probably not what you want in your src attribute value.
That is why Dimitre Novatchev used normalize-space() in his answer. Applying that to the example above:
<img>
<xsl:attribute name="src">
<xsl:value-of select="normalize-space(node())" />
<xsl:text>.jpg</xsl:text>
</xsl:attribute>
</img>
If you get rid of the <xsl:text> as Fabiano's solution suggests, then you could also do this:
<img>
<xsl:attribute name="src"><xsl:value-of select="normalize-space(node())" />.jpg</xsl:attribute>
</img>
Just remove the tag xsl:text, in this case, you won't need it. Try this:
<img>
<xsl:attribute name="src">
<xsl:value-of select="concat(node(), '.jpg')"/>
</xsl:attribute>
</img>
I didn't test it, but it should work. =)
<img>
<xsl:attribute name="src">
<xsl:value-of select="my_photo/#href" />
</xsl:attribute>
</img>
<my_photo href="folder/poster.jpg" />
Is it possible to add text from a xsl variable to the inside of a html tag something like this?
<xsl:variable name="selected">
<xsl:if test="#class = 'selected'"> class="selected"</xsl:if>
</xsl:variable>
<li{$selected}></li>
Try this:
<xsl:element name="li">
<xsl:if test="#class = 'selected'">
<xsl:attribute name="class">
selected
</xsl:attribute>
</xsl:if>
</xsl:element>
Optionally, the xsl:if could be nested in the xsl:attribute, instead of the other way around, if a class="" is desired. As already mentioned, it is unwise to write this as literal text.
You should not attempt to write this as literal text, instead look at xsl:element and xsl:attribute. Rough example:
<xsl:element name="li">
<xsl:attribute name="class">
<xsl:value-of select="$selected" />
</xsl:attribute>
</xsl:element>
Full documentation here.
Note that if you are careful enough to make it its first child, you can use <xsl:attribute> directly inside of your <li> tag, instead of using <xsl:element>
<li>
<xsl:if test="$selected">
<!-- Will refer to the last opened element, li -->
<xsl:attribute name="class">selected</xsl:attribute>
</xsl:if>
<!-- Anything else must come _after_ xsl:attribute -->
</li>
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