Retrieve all attribute values โ€‹โ€‹from XML using XSLT

I cannot figure out how to access all the attributes in a tag from an XML document.

Say I have the following XML:

<names> <name firstname="Rocky" lastname="Balboa" divider=", "/> <name firstname="Ivan" lastname="Drago" divider=", "/> </names> 

I need the following output: Rocky Balboa, Ivan Drago,

I currently have:

 <xsl:for-each select="names/name"> <xsl:value-of select="@firstname"/> <xsl:value-of select="@lastname"/> <xsl:value-of select="@divider"/> </xsl:for-each> 

I am wondering if it is possible to do this only in one sense - to choose, and not to do three of them. Therefore, to clarify, I want to be able to display all the attributes in a tag with one single value, select. Is it possible?

Thanks.

+4
source share
5 answers

Since I'm not sure that using xsl:value-of is a tough requirement, maybe something like the following might be what you are blocking for.

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output indent="yes"/> <xsl:template match="name" mode ="print" > <xsl:value-of select="@firstname"/> <xsl:text> </xsl:text> <xsl:value-of select="@lastname"/> <xsl:value-of select="@divider"/> </xsl:template> <xsl:template match="/"> <xsl:apply-templates select="names/name" mode="print"/> </xsl:template> </xsl:stylesheet> 

You can use <xsl:apply-templates select="names/name" mode="print"/> at any position that you have considered about using the value of one line for all attributes.
The above pattern will generate the following result:

 Rocky Balboa, Ivan Drago, 

Update drawer output without using attribute names:

 <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output indent="yes"/> <xsl:template match="name" mode ="print" > <xsl:for-each select="@*" > <xsl:if test="not(position() = last() or position() = 1)"> <xsl:text> </xsl:text> </xsl:if> <xsl:value-of select="."/> </xsl:for-each> </xsl:template> <xsl:template match="/"> <xsl:apply-templates select="names/name" mode="print"/> </xsl:template> </xsl:stylesheet> 
+3
source

try the following:

 <xsl:template match="/"> <xsl:for-each select="names/name/@*"> <xsl:value-of select="concat( ., ' ')"/> </xsl:for-each> </xsl:template> 
+1
source

If you can use XSLT 2.0, you can do something like this:

 <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text"/> <xsl:template match="text()"/> <xsl:template match="*[@*]"> <xsl:value-of select="@*[not(name()='divider')]" separator=" "/> <xsl:value-of select="@divider"/> <xsl:apply-templates/> </xsl:template> </xsl:stylesheet> 

This will result in the export of all attributes, and you will not control the order, so if you want to specify the order, you can either use the sequence:

 <xsl:value-of select="(@firstname,@lastname)" separator=" "/> 

or do xsl:apply-templates with xsl:sort to sort the name() attributes (or something else). Let me know if you want to give an example.

0
source

In XSLT 2.0, the following works:

 <xsl:for-each select="names/name"> <xsl:value-of select="@firstname, @lastname, @divider"/> </xsl:for-each> 

and in 3.0 you can do:

 <xsl:value-of select="names/name!(@firstname, @lastname, @divider)"/> 

although you may need to make adjustments to get the gaps the way you want it.

0
source

You can use this XPath @ * to get all attributes, for example:

 <xsl:template match="/*"> <xsl:for-each select="@*"> <xsl:value-of select="concat(name(), ': ', ., ' ')"/> </xsl:for-each> </xsl:template> 

This will allow you to use only one value to select the desired result. It takes into account all the attributes.

This should be enough advice for you to understand things. Let me know if you have any other questions.

-1
source

Source: https://habr.com/ru/post/1480980/


All Articles