18

Situation:

I have a simple XML document that contains image information. I need to transform it into HTML. However, I can't see where the open tag is and when I use the XSL code below, it shows the following error message:

"Cannot write an attribute node when no element start tag is open."

XML content:

<root>
    <HeaderText>
        <HeaderText>Dan Testing</HeaderText>
    </HeaderText>
    <Image>
        <img width="100" height="100" alt="FPO lady" src="/uploadedImages/temp_photo_small.jpg"/>
    </Image>
    <BodyText>
        <p>This is a test of the body text<br  /></p>
    </BodyText>
    <ShowLinkArrow>false</ShowLinkArrow>
</root>

XSL code:

<xsl:stylesheet version="1.0" extension-element-prefixes="msxsl"
    exclude-result-prefixes="msxsl js dl" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:js="urn:custom-javascript" xmlns:msxsl="urn:schemas-microsoft-com:xslt"
    xmlns:dl="urn:datalist">
    <xsl:output method="xml" version="1.0" omit-xml-declaration="yes" indent="yes" encoding="utf-8"/>
    <xsl:template match="/" xml:space="preserve">
        <img>
            <xsl:attribute name="width">
                100
            </xsl:attribute>
            <xsl:attribute name="height">
                100
            </xsl:attribute>
            <xsl:attribute name="class">
                CalloutRightPhoto
            </xsl:attribute>
            <xsl:attribute name="src">
                <xsl:copy-of select="/root/Image/node()"/>
            </xsl:attribute>
        </img>
    </xsl:template>
</xsl:stylesheet>
Eric J. Price
  • 2,740
  • 1
  • 15
  • 21
Danimal
  • 7,672
  • 8
  • 47
  • 57
  • The title needs to be improved. There is no context of where or what you want to "add an image" and this title in its present form throws off search results. – Jeffrey M Sep 01 '22 at 12:41

5 Answers5

27

Just to clarify the problem here - the error is in the following bit of code:

<xsl:attribute name="src">
    <xsl:copy-of select="/root/Image/node()"/>
</xsl:attribute>

The instruction xsl:copy-of takes a node or node-set and makes a copy of it - outputting a node or node-set. However an attribute cannot contain a node, only a textual value, so xsl:value-of would be a possible solution (as this returns the textual value of a node or nodeset).

A MUCH shorter solution (and perhaps more elegant) would be the following:

<img width="100" height="100" src="{/root/Image/node()}" class="CalloutRightPhoto"/>

The use of the {} in the attribute is called an Attribute Value Template, and can contain any XPATH expression.

Note, the same XPath can be used here as you have used in the xsl_copy-of as it knows to take the textual value when used in a Attribute Value Template.

samjudson
  • 56,243
  • 7
  • 59
  • 69
  • I am trying to solve something very similar. I need to generate word reports from a PHP application for what I am transforming XML with XSLT. Does the above solution work to generate word 2007 documents? – ivantxo Dec 06 '11 at 01:30
  • No, the above is not for generating word documents, but simply for creating an tag from the given XML input. If you want to generate Word documents using XSLT then good luck, as it is very complex. – samjudson Dec 19 '11 at 16:37
4

Shouldn't that be:

<xsl:value-of select="/root/Image/img/@src"/>

? It looks like you are trying to copy the entire Image/img node to the attribute @src

Cory Foy
  • 7,202
  • 4
  • 31
  • 34
  • +1 This worked for me. I haven't tried with "/root/Image/node()" because that just doesn't seem to make any sense.. – Jules Colle Nov 04 '10 at 17:46
4

In order to add attributes, XSL wants

<xsl:element name="img">
     (attributes)
</xsl:element>

instead of just

<img>
     (attributes)
</img>

Although, yes, if you're just copying the element as-is, you don't need any of that.

harpo
  • 41,820
  • 13
  • 96
  • 131
3

Never mind -- I'm an idiot. I just needed <xsl:value-of select="/root/Image/node()"/>

Danimal
  • 7,672
  • 8
  • 47
  • 57
0

The other option to try is a straightforward

<img width="100" height="100" src="/root/Image/image.jpeg" class="CalloutRightPhoto"/>

i.e. without {} but instead giving the direct image path

m_cheung
  • 331
  • 3
  • 6