Christian Nagel's OneNotes

.NET Training, Consulting, Coaching - C#, Web Services, Enterprise Services, ASP.NET, Whidbey, Longhorn and More!

Sponsors

Affiliations

Books I've written

INETA UG Leaders

My Blogroll

XSLT: Converting multiple elements to one attribute

I've received a question how to convert multiple XML elements to a values for a single attribute. Here is the information about how this can be done with XSLT.

The XML source:

<Article>
 <Head>
  <Title>.NET Enterprise Services</Title>
  <MainCategory></MainCategory>
  <Keyword>Framework</Keyword>
  <Keyword>C#</Keyword>
  <Keyword>Enterprise Services</Keyword>
 </Head>
 <Body>
 </Body>
 <Info>
 </Info>
</Article>

From this source the elements <Keyword> should be converted to this result:

<META name="keywords" content="Framework, C#, Enterprise Services">

This is done with this XSLT transformation:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Demo Style sheet to convert multiple elements to a single attribute value 
-->
<xsl:stylesheet xmlns:xsl="
http://www.w3.org/1999/XSL/Transform"
    version="1.0">
 <xsl:output method="html" indent="yes"/>
 <xsl:template match="/">
  <HTML>
   <HEAD>
    <xsl:element name="META">
     <xsl:attribute name="name">keywords</xsl:attribute>
     <xsl:attribute name="content">
      <xsl:for-each select="Article/Head/Keyword">
       <xsl:value-of select="."/>
       <xsl:if test="position() != last()">, </xsl:if>
      </xsl:for-each>
     </xsl:attribute>
    </xsl:element>
    <TITLE>
    </TITLE>
   </HEAD>
   <BODY></BODY>
  </HTML>
 </xsl:template>
</xsl:stylesheet>

<xsl:element> and <xsl:attribute> allows dynamic creation of elements and attributes. <xsl:element name="META"> defines the element <META>. <xsl:attribute name="name">keywords</xsl:attribute> results in <META name="keywords">. The content of the attribute content is created dynamically with a selection of each <Article><Head><Keyword> element, and in between of these values a semicolon is added. <xsl:if test=position() != last()"> checks if the <Keyword> element was not the last one, as with the last one no more semicolon is used.

I really like the XSLT editor and debugger of Visual Studio 2005. This makes it easy to create XSLT files.

Update: Bryan has another option to create the Meta tags:

 <xsl:template match="/">
  <HTML>
   <HEAD> 
    <META name="keywords">
     <xsl:attribute name="Content">
      <xsl:apply-templates select="Article/Head/Keyword" />
     </xsl:attribute>
    </META>
    <TITLE>
    </TITLE>
   </HEAD>
   <BODY></BODY>
  </HTML>
 </xsl:template>
 
 <xsl:template match="Article/Head/Keyword" >
  <xsl:value-of select="."/>
  <xsl:if test="following-sibling::Keyword">,</xsl:if>
 </xsl:template>

Christian

Comments

bryan said:

how about

&lt;meta name="keywords"&gt;&lt;xsl:attribute name="Content"&gt;&lt;xsl:apply-templates select="Article/Head/Keyword" mode="csv"/&gt;&lt;/xsl:attribute&gt;&lt;/meta&gt;

then in the template for Keyword in the csv mode
&lt;xsl:value-of select="."/&gt;&lt;xsl:if test="following-sibling::Keyword"&gt;,&lt;/xsl:if&gt;
# September 24, 2004 4:02 AM

Christian said:

Yes, this is another option :-)
# September 25, 2004 9:33 AM

brianin3d said:

This is exactly what I was looking! Thanks a lot.

# February 13, 2009 11:18 AM

saravana said:

I need help to get a xsl format for the below xml code

note:- path or file name is dynamic

pls help me.

<paths>

<path

  kind="file"

  action="M">/trunk/hpsim-core/package/win/installShell/content/ko_strings.js</path>

<path

  kind="file"

  action="M">/trunk/hpsim-core/package/win/installShell/content/zh_TW_strings.js</path>

<path

  kind="file"

  action="M">/trunk/hpsim-core/package/win/installShell/content/account-credentials.js</path>

<path

  kind="file"

  action="M">/trunk/hpsim-core/package/win/installShell/content/zh_CN_strings.js</path>

</paths>

# July 5, 2011 4:39 AM

Kitchens said:

I don't create many responses, but i did some searching and wound up here XSLT: Converting multiple elements to one attribute - Christian Nagel's OneNotes.

And I actually do have a couple of questions for you if you do not mind.

Could it be only me or does it look like some of the responses look

like they are coming from brain dead individuals? :-P And, if you are posting at other

social sites, I'd like to follow anything new you have to post. Would you list of all of your social pages like your twitter feed, Facebook page or linkedin profile?

# April 17, 2013 12:45 PM