Home > Software engineering >  XSLT to concatenate element name with attribute value
XSLT to concatenate element name with attribute value

Time:03-09

how could I make out of an XML like this:

<nameGroup index="1"> 
    <name>SOME NAME</name>
    <country>CN</country>
</nameGroup>
<nameGroup index="2">
    <name>SOME OTHER NAME</name>
    <country>IQ</country>
</nameGroup>

To an XML like this, concatenating element name with attribute value:

<nameGroup><name1>SOME NAME</name1><country1>CN</country1></nameGroup>
<nameGroup><name2>SOME OTHER NAME</name2><country2>IQ</country2></nameGroup>

with a proper XSLT?

I tried with something like this:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

  <xsl:template match="/">
        <xsl:copy>
            <xsl:apply-templates select="*" />
        </xsl:copy>
    </xsl:template>
  
  <xsl:template match="nameGroup/name">
      <xsl:variable name="pos">
          <xsl:number count="info"/>
      </xsl:variable>
      <xsl:element name="{local-name()}{$pos}">
          <xsl:apply-templates/>
     </xsl:element>
   </xsl:template>
   
   <xsl:template match="*">
        <xsl:element name="{local-name()}">
            <xsl:apply-templates select="@* | node()" />
        </xsl:element>
    </xsl:template>

</xsl:stylesheet>

But the result is just something like this:

<nameGroup>1 
  <name>SOME NAME</name>
  <country>CN</country>
</nameGroup>
<nameGroup>2
  <name>SOME OTHER NAME</name>
  <country>IQ</country>
 </nameGroup>

Anyone knows how can I obtain the desired result? Thanks!

PS: I made it like this (if anyone would search for this in the future): (with mr. Michael Kay's help)

<?xml version='1.0' encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="*">
        <xsl:element name="{local-name()}{../@index}">
            <xsl:apply-templates select="* | node()" />
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

CodePudding user response:

I can't imagine why anyone would want to do this; I also can't see why you find it difficult. You simply need the rule

<xsl:template match="namegroup/*">
  <xsl:element name="{local-name()}{../@index}">
    <xsl:value-of select="."/>
  </xsl:element>
</xsl:template>
  • Related