Here is probably the simplest solution that will convert any children-elements of ITEM
to its attributes and will reproduce everything else as is, while converting the element names to any desired attribute names:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<!-- -->
<xsl:strip-space elements="*"/>
<xsl:variable name="vrtfNameMapping">
<item name="SERIALNUMBER" newName="serialNumber"/>
<item name="LOCATION" newName="location"/>
<item name="BARCODE" newName="barcode"/>
</xsl:variable>
<!-- -->
<xsl:variable name="vNameMapping" select=
"document('')/*/xsl:variable[@name='vrtfNameMapping']"/>
<!-- -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<!-- -->
<xsl:template match="ITEM/*">
<xsl:attribute name=
"{$vNameMapping/*[@name=name(current())]/@newName}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
when the above transformation is applied on the provided XML document:
<INVENTORY>
<ITEM>
<SERIALNUMBER>something</SERIALNUMBER>
<LOCATION>something</LOCATION>
<BARCODE>something</BARCODE>
</ITEM>
</INVENTORY>
the wanted result is produced:
<INVENTORY>
<ITEM serialNumber="something" location="something" barcode="something"/>
</INVENTORY>
Do note the following:
The use of the identity rule
The use of <xsl:strip-space elements="*"/>
The use of the variable vrtfNameMapping
without any xxx:node-set()
extension function.
The fact that we handle any mapping between a name and a newName, not only simple lower-casing.