468,257 Members | 1,408 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,257 developers. It's quick & easy.

.net framework XSLT processor appears to be broken

I stumbled upon this while developing a custom XPathNavigator.
It appears that copy action for attributes is broken in the .net
framework XSLT processor.

The intent was to just copy the entities and attributes from the
source XML into the output using simple "identity" like XSLT:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/ | @* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

This appears to loose the attributes of non-leaf entities when run
over a custom XPathNavigator. The problem appears to be related to the
order of processing. When run over a custom XPathNavigator the child
entities are processed before the attributes in the above XSLT.

The situation can be recreated over a regular XmlDocument using
following XSLT:

This does not work (notice the order of processing - attributes are
processed first):

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="*|/">
<xsl:copy>
<xsl:apply-templates select="*" />
<xsl:apply-templates select="@*" />
</xsl:copy>
</xsl:template>

<xsl:template match="@*">
<xsl:copy-of select="." />
</xsl:template>
</xsl:stylesheet>

This does work (notice the order of processing - attributes are
processed first)

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="*|/">
<xsl:copy>
<xsl:apply-templates select="@*" />
<xsl:apply-templates select="*" />
</xsl:copy>
</xsl:template>

<xsl:template match="@*">
<xsl:copy-of select="." />
</xsl:template>
</xsl:stylesheet>

Here is a quick and dirty code snippet:
---------------------------------------------------------
String xsltFileName = "test.xslt";
XmlReader transfromReader = new XmlTextReader(xsltFileName);

XslTransform transform = new XslTransform();
transform.Load(transfromReader);

StringBuilder result = new StringBuilder();
TextWriter writer = new StringWriter(result);

String xmltestFileName = "test.xml";
XmlDocument testDocument = new XmlDocument();
testDocument.Load(xmltestFileName);

transform.Transform(testDocument,null,writer);
---------------------------------------------------------

Any XML document with several levels of entity nesting and some
attributes at each level can be used to recreate the situation.
Nov 12 '05 #1
3 1531
Alex wrote:
I stumbled upon this while developing a custom XPathNavigator. It appears that copy action for attributes is broken in the .net
framework XSLT processor.

The intent was to just copy the entities and attributes from the
source XML into the output using simple "identity" like XSLT:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/ | @* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

This appears to loose the attributes of non-leaf entities when run
over a custom XPathNavigator. The problem appears to be related to the
order of processing. When run over a custom XPathNavigator the child
entities are processed before the attributes in the above XSLT.
Well, it works for me (and always worked). Apparently the problem is
with your custom XPathNavigator? Provide more information about it.
The situation can be recreated over a regular XmlDocument using
following XSLT:

This does not work (notice the order of processing - attributes are
processed first):

You meant attributes are processed after elements. This shouldn't work
according to the XSLT spec. Attributes must be processed before child
nodes. Identity transformatio assures it by using
<xsl:apply-templates select="@* | node()"/>
Here xsl:apply-templates instruction processes selected nodes in
document order and attributes go before child nodes in document order by
definition.
--
Oleg Tkachenko [XML MVP]
http://blog.tkachenko.com
Nov 12 '05 #2
Thank you for the reply.
Well, it works for me (and always worked). Apparently the problem is
with your custom XPathNavigator? Provide more information about it.
A custom XPathNavigator does not have any real ability to influence
the
order of processing (attributes vs. child elements). In my case the
XPathNavigator exposes a very complex repository as virtual XML...

The navigator only implements the minimum set of necessary functions
like MoveNext(), etc. It does not implement any custom XPath engine,
etc.

What I observe is that in the case of Identity transformation the
attributes
are processed after the child elements when transforming my
XPathNavigator.

However when the same transformation is used to transform a
XmlDocument
it processes the attributes first.

You meant attributes are processed after elements. This shouldn't workaccording to the XSLT spec. Attributes must be processed before child
nodes. Identity transformatio assures it by using
<xsl:apply-templates select="@* | node()"/>
Here xsl:apply-templates instruction processes selected nodes in
document order and attributes go before child nodes in document order bydefinition.

Nov 12 '05 #3
Alex wrote:
A custom XPathNavigator does not have any real ability to influence
the
order of processing (attributes vs. child elements). In my case the
XPathNavigator exposes a very complex repository as virtual XML...

The navigator only implements the minimum set of necessary functions
like MoveNext(), etc. It does not implement any custom XPath engine,
etc.
Hmmm, you are right. I wonder how the problem can be traced. Can you
dump a sequence of calls to your XPathNavigator? Try to debug it to see
how it gets moved, sometimes weird things might happen just because of a
single forgotten Clone() call.
What I observe is that in the case of Identity transformation the
attributes
are processed after the child elements when transforming my
XPathNavigator.


Try modified identity transformation to find out where the problem is:

<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>

--
Oleg Tkachenko [XML MVP]
http://blog.tkachenko.com
Nov 12 '05 #4

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

1 post views Thread by Doug Farrell | last post: by
8 posts views Thread by Ola Natvig | last post: by
10 posts views Thread by daz_oldham | last post: by
1 post views Thread by Sergey Dubinets | last post: by
4 posts views Thread by =?Utf-8?B?REZC?= | last post: by
reply views Thread by kermitthefrogpy | last post: by
reply views Thread by zattat | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.