Background
The other day, I was working on an XSLT that transforms XML into HTML page. By fluke or some other means I got this error I wasn’t prepared for:
Error
Attribute and namespace nodes cannot be added to the parent element after a text, comment, pi, or sub-element node has already been added.
XSLT Source Code
I repeated the error by creating this XSLT code.
<xsl:template match=“/Books“>
<html>
<body>
<h2>Select a book to read today:</h2>
<xsl:element name=“select“>
<xsl:attribute name=“name“>books</xsl:attribute>
<xsl:for-each select=“Book“>
<xsl:element name=“option“>
<xsl:value-of select=“Title“/>
<xsl:attribute name=“value“>
<xsl:value-of select=“Title“/>
</xsl:attribute>
</xsl:element>
</xsl:for-each>
<xsl:element name=“select“>
</xsl:element>
</xsl:element>
</body>
</html>
</xsl:template>
XML Input
<Books>
<Book>
<Title>OOP Demystified</Title>
<Author>James Keogh</Author>
<Language>English</Language></Book>
<Book>
<Title>Spoken from the Heart</Title>
<Author>Laura Bush</Author><Language>English</Language>
</Book>
</Books>
Solution
The error message is self-explanatory really. To get round this problem, we need to move “<xsl:value-of select=“Title“/>”
to after the attributes we wish to set. This is because the attributes for that element will need to be set first before all the
values are set.
<xsl:template match=“/Books“>
<html>
<body>
<h2>Select a book to read today:</h2>
<xsl:element name=“select“>
<xsl:attribute name=“name“>books</xsl:attribute>
<xsl:for-each select=“Book“>
<xsl:element name=“option“>
<xsl:attribute name=“value“>
<xsl:value-of select=“Title“/>
</xsl:attribute>
<xsl:value-of select=“Title“/> <!– Move to here, after attribute –>
</xsl:element>
</xsl:for-each>
<xsl:element name=“select“/>
</xsl:element>
</body>
</html>
</xsl:template>
Tips
- Debug your XSLT by opening it in Visual Studio.
- Point to the input XML from the Properties window for the XSLT page.
- Put breakpoint as you would normally do.
- Transform the XML by clicking Debug XSLT in the XML Editor on the toolbar. Don’t press F5/F6!
- Then you could start to use your usual debugging keys like F10, F11, etc.
Have fun debugging your XSLT!
Leave a Reply