I am trying to transform 1 XML document to another using XSLT. I want to call the value from my source XML to the element in my result XML as the value of an attribute.

Source code-

<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="test.xsl"?>
<catalog>
<cd>
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
<cd>
<title>Hide your heart</title>
<artist>Bonnie Tyler</artist>
<country>UK</country>
<company>CBS Records</company>
<price>9.90</price>
<year>1988</year>
</cd>
</catalog>

Want output as-
<root>
<singer name=”Bob Dylan”>
<!--this name is the value of "artist"-->
<title>Empire Burlesque</title>
</singer>
<singer name=”Bonnie Tyler”/>
<title>Hide your heart</title>
</singer>
</root>

I don’t even know whether it is possible or not using XSLT. Please advise.

Dani AI

Generated

Brief summary: the approaches in this thread are all on the right track. correctly showed creating an attribute from the child element value; the reason ’s prefixed attribute failed was almost always one of two things — the namespace prefix (ab:) wasn’t declared on the stylesheet, or the stylesheet was trying to read an attribute (@artist) when artist is an element. Declaring the namespace on the XSLT root and emitting the attribute in that namespace fixes it.

A small, complete pattern that works cleanly is to declare the desired output prefix on the stylesheet and use an attribute-value-template to populate the namespaced attribute directly from the child element. For example:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:ab="http://example.com/ab"
                version="1.0">

  <xsl:template match="/catalog">
    <root>
      <xsl:for-each select="cd">
        <singer ab:name="{artist}">
          <title><xsl:value-of select="title"/></title>
        </singer>
      </xsl:for-each>
    </root>
  </xsl:template>

</xsl:stylesheet>

Troubleshooting checklist:

  • Make sure xmlns:ab="..." is declared on xsl:stylesheet (or a literal result element) so ab: resolves.
  • Use artist (element) not @artist (attribute) unless your source really has an attribute.
  • If you prefer xsl:attribute, using a prefixed name (for example ab:name) works only when the ab prefix is declared in the stylesheet.
  • If the serializer chooses a different prefix for the same URI, explicitly declaring the prefix on the stylesheet ensures the prefix you want appears.

Tie-back: ’s technique is correct for non-namespaced attributes; the extra step for a namespaced attribute is the namespace declaration that initially missed.

Recommended Answers

All 3 Replies

I'm not an expert in XSLT but I think you can do that with something like this:

<singer>
	<xsl:attribute name="name">
		<xsl:value-of select="artist"/> 
	</xsl:attribute>
	<title><xsl:value-of select="title"/></title>
</singer>

Thanks for the help me655321. I am new to XSLT and getting stuck in things like this.
It's working for me, however, my need is bit different (My apology as i should have mentioned it earlier).

i need to use a namespace in the resultant XML.
<root>
<singer ab:name=”Bob Dylan”>
<!--need to show "ab:name"-->
<title>Empire Burlesque</title>
</singer>
<singer ab:name=”Bonnie Tyler”/>
<title>Hide your heart</title>
</singer>
</root>


I tried the same thing with this "ab:name" and might be thats the reason it was not working, because when i try it without ":" it works.

<singer>
<xsl:attribute name="ab:name"> <!-- this one is not working>
<xsl:value-of select="@artist"/> </xsl:attribute>
<title><xsl:value-of select="title"/> </title>
</singer>
<singer>
<xsl:attribute name="abname"> <!-- this one is working>
<xsl:value-of select="@artist"/>
</xsl:attribute>
<title><xsl:value-of select="title"/></title>
</singer>


Please advise.

I got solution for it. thanks.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.