user2879555
user2879555

Reputation: 11

Convert xml attribute and elements to elements

I need a help in XML transformations. My Input xml is

<Book BookType="PAPER" BookID="23456" AuthorCD="578"> my Book Name </Book>

I need the output in below format

<Book> 
 <BookType>PAPER</BookType>
 <BookID>23456</BookID>
 <AuthorCD>578</AuthorCD>
 <Book>my Book Name </Book>
</Book>

I am trying below transformation

<xsl:template match=Book">
<xsl:copy>
<xsl:if test="@*">
<xsl:for-each select="@*">
<xsl:element name="{name()}">
  <xsl:value-of select="." />
      </xsl:element>
       </xsl:for-each>
     </xsl:if>
   <xsl:apply-templates />
 </xsl:copy>
</xsl:template>

But its out put is coming like below. How to get the "my book name" is not appearing in expected format.

<Book xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <BookType>PAPER</BookType>
    <BookID>23456</BookID>
    <AuthorCD>578</AuthorCD>
     my Book Name
</<Book>

Upvotes: 1

Views: 1227

Answers (3)

Martin Honnen
Martin Honnen

Reputation: 167726

Write a template for the Book element and another one for its attributes:

<xsl:template match="Book">
  <xsl:copy>
    <xsl:apply-templates select="@*"/>
    <Book>
      <xsl:value-of select="."/>
    </Book>
  </xsl:copy>
</xsl:template>
<xsl:template match="Book/@*">
  <xsl:element name="{name()}">
    <xsl:value-of select="."/>
  </xsl:element>
</xsl:template>

Upvotes: 4

Bartosz Bilicki
Bartosz Bilicki

Reputation: 13275

You are getting "my book name" output because default template for text nodes kicks in. Default template rules work as given below:

  • get text value for attributes and text nodes
  • apply defined templates (or defaults if nothing is defined).
  • ignore comments and processing instructions

According to above rules, atrribute names and element names are not to be found in output.

Learn more about default templates

For your solution to work as expected, you need to add rule for text nodes inside Book element:

<xsl:template match="Book/text()">
 <Book>
  <xsl:value-of select="."/>
 </Book>
</xsl:template>

Upvotes: 0

M.Ali
M.Ali

Reputation: 69594

try this

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>

  <xsl:template match="@*">
    <xsl:element name="{name()}"><xsl:value-of select="."/></xsl:element>
  </xsl:template>
</xsl:stylesheet>

Upvotes: 0

Related Questions