XSL transforms

J

Joachim

I have a XML file with belonging XSL file. Opening the XML file in IE7 works
just fine. But when using the following code I get the error message:

"Attribute and namespace nodes cannot be added to the parent element after a
text, comment, pi, or sub-element node has already been added."

XPathNavigator nav =
xml_document.DocumentElement.CreateNavigator();
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load(xsl_document_location);
xslt.Transform(nav, null, output_stream);

My XSL code contains some portions of code like this:

<xsl:element name="img">
<xsl:attribute name="class">drawing</xsl:attribute>
<xsl:attribute name="width">100%</xsl:attribute>
<xsl:attribute name="src">
<xsl:value-of select="Folder" />
<xsl:text disable-output-escaping="yes">/</xsl:text>
<xsl:value-of select="Filename" />
</xsl:attribute>
</xsl:element>

A thread I found
(http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=627581&SiteID=1) says
that attribute nodes should be created before element nodes. This is find
very strange since the attribute is a part of the element, not vice versa.
Anyone?
 
A

Arto Viitanen

Joachim kirjoitti:
I have a XML file with belonging XSL file. Opening the XML file in IE7 works
just fine. But when using the following code I get the error message:

"Attribute and namespace nodes cannot be added to the parent element after a
text, comment, pi, or sub-element node has already been added."

XPathNavigator nav =
xml_document.DocumentElement.CreateNavigator();
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load(xsl_document_location);
xslt.Transform(nav, null, output_stream);

My XSL code contains some portions of code like this:

<xsl:element name="img">
<xsl:attribute name="class">drawing</xsl:attribute>
<xsl:attribute name="width">100%</xsl:attribute>
<xsl:attribute name="src">
<xsl:value-of select="Folder" />
<xsl:text disable-output-escaping="yes">/</xsl:text>
<xsl:value-of select="Filename" />
</xsl:attribute>
</xsl:element>

xsl:attribute creates new attribute. xsl:text appends text to the
element. So xsl:text adds / to the <img> element, and
the end of the src attribute causes the error message.

I'd try

<xsl:variable name="slash"><xsl:text
disable-output-escaping="yes">/</xsl:text></xsl:variable>
<xsl:element name="img">
<xsl:attribute name="class">drawing</xsl:attribute>
<xsl:attribute name="width">100%</xsl:attribute>
<xsl:attribute name="src">
<xsl:value-of select="Folder" />
<xsl:value-of select="$slash" />
<xsl:value-of select="Filename" />
</xsl:attribute>
</xsl:element>

instead.
A thread I found
(http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=627581&SiteID=1) says
that attribute nodes should be created before element nodes. This is find
very strange since the attribute is a part of the element, not vice versa.

I guess it means, that subelements should be added after the attributes
are added.
 
P

Pavel Minaev

I have a XML file with belonging XSL file. Opening the XML file in IE7 works
just fine. But when using the following code I get the error message:

"Attribute and namespace nodes cannot be added to the parent element after a
text, comment, pi, or sub-element node has already been added."

            XPathNavigator nav =
xml_document.DocumentElement.CreateNavigator();
            XslCompiledTransform xslt = new XslCompiledTransform();
            xslt.Load(xsl_document_location);
            xslt.Transform(nav, null, output_stream);

My XSL code contains some portions of code like this:

        <xsl:element name="img">
          <xsl:attribute name="class">drawing</xsl:attribute>
          <xsl:attribute name="width">100%</xsl:attribute>
          <xsl:attribute name="src">
            <xsl:value-of select="Folder" />
            <xsl:text disable-output-escaping="yes">/</xsl:text>
            <xsl:value-of select="Filename" />
          </xsl:attribute>
        </xsl:element>

A thread I found
(http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=627581&SiteID=1) says
that attribute nodes should be created before element nodes. This is find
very strange since the attribute is a part of the element, not vice versa..

Actually, what this means is that attribute nodes for a given element
must be created before the child element nodes for that element. The
particular piece of code that you've posted doesn't have this problem,
but, apparently, some other one does. To quote the XSLT W3C
Recommendation (http://www.w3.org/TR/xslt#creating-attributes):

"The following are all errors:

- Adding an attribute to an element after children have been added to
it; implementations may either signal the error or ignore the
attribute."

IE XSLT implementation seems to be lax in that regard, probably
because it works with mutable DOM rather than forward-only writers,
and so the restriction doesn't make as much sense there.
 
M

Marc Gravell

attributes definitely follow elements in xslt - and I'm not convinced
that the error message relates to that particular element, but make
life simple; try something like:

<img class="drawing" width="100%" src="{Folder}/{Filename}"/>

Marc
 
M

Marc Gravell

Note I've posted an example (showing no problems in the above) in the
managed group. But note also the simpler syntax <img ... src="{Folder}/
{Filename}"/> is preferable.

Marc
 
G

GArlington

I have a XML file with belonging XSL file. Opening the XML file in IE7 works
just fine. But when using the following code I get the error message:

"Attribute and namespace nodes cannot be added to the parent element after a
text, comment, pi, or sub-element node has already been added."

XPathNavigator nav =
xml_document.DocumentElement.CreateNavigator();
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load(xsl_document_location);
xslt.Transform(nav, null, output_stream);

My XSL code contains some portions of code like this:

<xsl:element name="img">
<xsl:attribute name="class">drawing</xsl:attribute>
<xsl:attribute name="width">100%</xsl:attribute>
<xsl:attribute name="src">
<xsl:value-of select="Folder" />
<xsl:text disable-output-escaping="yes">/</xsl:text>
<xsl:value-of select="Filename" />
</xsl:attribute>
</xsl:element>

A thread I found
(http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=627581&SiteID=1) says
that attribute nodes should be created before element nodes. This is find
very strange since the attribute is a part of the element, not vice versa.
Anyone?

AFAIR you need to define complex types BEFORE you use them.
In your case <xsl:attribute name="src"> IS a complex type...
This may be the cause of the error...
 
M

Marc Gravell

xsl:attribute is defined by xslt itself; so as long as xsl points to the
right namespace this shouldn't be an issue.

Marc
 
P

Pavel Minaev

attributes definitely follow elements in xslt

They do not. I've quoted the XSLT specification which says, in plain
English, that it is not allowed to add any attributes after a child
element has been added. An XSLT processor may still allow it as an
extension, but it is not standard XSLT, and it would seem that
XslCompiledTransform follows the spec here.

It would be pretty tricky to write an attribute after a child element
to an XmlWriter, anyway...
 
P

Pavel Minaev

AFAIR you need to define complex types BEFORE you use them.
In your case <xsl:attribute name="src"> IS a complex type...
This may be the cause of the error...

<xsl:attribute> is not a type at all, and @src attribute should have
type xs:anyURI, which is not complex (but it is irrelevant here
anyway, since no type is being referenced in the XSLT snippet posted).
 
M

Marc Gravell

Yes, but if you consider the context of the OP's remark:
<q>
A thread I found [snip]says that attribute nodes should be created before
element nodes. This is find very strange since the attribute is a part of
the element, not vice versa. Anyone?
</q>
It seems clear to me that the OP is referring to the *containing* element.
And the attribute declarations definitely follow the *containing* element
declaration. If my phrasing was unfortunate then sorry for confusion; but I
was referring to the OPs remark. Yes, attribute declarations preceed other
*child* content nodes, but that isn't what I was referring to.

Either way, it is *still* simpler to use the inline syntax <img
src="{$foo}"/> ;-p

Marc
 
M

Marc Gravell

<xsl:attribute> is not a type at all

It is if you have a schema for xsd, such as xslt.xsd that ships with VS,
which defines:

<xs:complexType name="attribute" mixed="true">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:group ref="char-instructions"/>
</xs:choice>
<xs:attribute name="name" type="xs:string" use="required" />
<xs:attribute name="namespace" type="xs:string" />
<xs:attribute ref="xml:space" />
</xs:complexType>

and uses it in the "instructions" and "attribute-set" groups via:
<xs:element name="attribute" type="attribute"/>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top