0

I am unable to perform encode of node content while transforming with XSLT. My input XML is Below:

  <?xml version="1.0" encoding="iso-8859-1"?>
  <!-- Edited by XMLSpy® -->
  <catalog>
   <cd>
     <title>D-Link</title>
     <artist>Bob Dylan</artist>
     <country>USA</country>
   </cd>
   <cd>
    <title>x-<i>NetGear</i></title>
    <artist>Rod Stewart</artist>
    <country>UK</country>
   </cd>
   <cd>
    <title>LG</title>
    <artist>Andrea Bocelli</artist>
    <country>EU</country>
   </cd>
 </catalog>

And the XSLT is:

<?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="/">
  <Root>
    <xsl:for-each select="catalog/cd">
    <Product>
      <xsl:attribute name="title">          
        <xsl:copy-of select="title/node()"/>          
      </xsl:attribute>
    </Product>
   </xsl:for-each>
  </Root>
 </xsl:template>
</xsl:stylesheet>

Currently I am getting an error as : An item of type 'Element' cannot be constructed within a node of type 'Attribute' while it is iterating for second CD title.

The expected output is below:

<?xml version="1.0" encoding="utf-8"?>
<Root>
  <Product title="D-Link" />
  <Product title="x-&lt;i&gt;NetGear&lt;/i&gt;" />
  <Product title="LG" />
</Root>

Could anyone help me with above issue?

TempTracer
  • 137
  • 5

1 Answers1

1

<xsl:copy-of> will attempt what its name implies: It will try to copy the selected nodes, including elements, into the attribute. Of course, the attribute can only contain text, not elements.

You can create "fake tags" using a dedicated template:

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

  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/">
    <Root>
      <xsl:for-each select="catalog/cd">
        <Product>
          <xsl:attribute name="title">
            <xsl:apply-templates select="title/node()" mode="escape-xml"/>
          </xsl:attribute>
        </Product>
      </xsl:for-each>
    </Root>
  </xsl:template>

  <xsl:template match="*" mode="escape-xml">
    <xsl:value-of select="concat('&lt;',local-name(),'>')"/>
    <xsl:apply-templates select="node()"/>
    <xsl:value-of select="concat('&lt;/',local-name(),'>')"/>
  </xsl:template>
</xsl:stylesheet>

This will deliver the desired result.

Thomas W
  • 14,757
  • 6
  • 48
  • 67
  • Thanks Thomas. On the same lines, there is another good solution at http://stackoverflow.com/questions/6696382/xslt-how-to-convert-xml-node-to-string – TempTracer Jul 08 '13 at 14:00