Discussion:
msxsl:node-set() has failed
(too old to reply)
Sam Akiwumi
2004-03-05 14:52:55 UTC
Permalink
Hi

I am trying to get the transform the following XML

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl"
href="C:\Projects\kmc.co.uk\e-commerce\Rules Engine\XSL
Stylesheets\Nodeset.xsl"?>
<books>
<book author="Michael Howard">Writing Secure Code</book>
<book author="Michael Kay">XSLT Reference</book>
</books>

Using the following XSL
----------
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:user="http://www.contoso.com">
<xsl:variable name="books"
select="document('file://C:\Projects\kmc.co.uk\e-commerce\Rules
Engine\XML\Untitled2.xml')"/>
<xsl:template match="/">
<authors>
<xsl:for-each select="msxsl:node-set($books)/books/book">
<author><xsl:value-of select="@author"/></author>
</xsl:for-each>
</authors>
</xsl:template>
</xsl:stylesheet>
---------------------------
I have created code in C# to do the transformation and I am using the
built-in XSLT Processor (implements the XSL Transformations (XSLT)
Version 1.0 recommendation).

Code
----------------------------
//Load the file to transform.
XPathDocument doc = new XPathDocument(xmlFile);

// Create a resolver with default credentials.
XmlUrlResolver resolver = new XmlUrlResolver();
resolver.Credentials = System.Net.CredentialCache.DefaultCredentials;

//Load the stylesheet
XmlDocument xsl = new XmlDocument();
xsl.Load(stylesheet);
XslTransform xslt = new XslTransform();
xslt.Load(xsl, resolver, this.GetType().Assembly.Evidence);

//Create an XmlTextWriter which outputs to the console.
StreamWriter outputWriter = new StreamWriter("C:\\Temp\\result1.xml");
XmlTextWriter writer = new XmlTextWriter(outputWriter);

//Transform the file and send the output to the console.
xslt.Transform(doc, null, writer, resolver);
----------------------------------

When I run the code, I get the an exception (below) which says the
Function 'msxsl:node-set()' has failed.

EXCEPTION
-----------------
InnerEx=System.Xml.Xsl.XsltException: Cannot convert the operand to
'Result tree fragment'.
at System.Xml.Xsl.XsltFunctionImpl.ToNavigator(Object argument)
at System.Xml.Xsl.FuncNodeSet.Invoke(XsltContext xsltContext,
Object[] args,
XPathNavigator docContext)
at System.Xml.XPath.XsltFunction.InvokeFunction(XPathNavigator qy,
XPathNodeI
terator iterator)
-----------------

Any ideas why this is happening? tx
Sam

*** Sent via Developersdex http://www.developersdex.com ***
Don't just participate in USENET...get rewarded for it!
Oleg Tkachenko [MVP]
2004-03-05 15:30:58 UTC
Permalink
Post by Sam Akiwumi
<xsl:variable name="books"
select="document('file://C:\Projects\kmc.co.uk\e-commerce\Rules
Engine\XML\Untitled2.xml')"/>
<xsl:template match="/">
<authors>
<xsl:for-each select="msxsl:node-set($books)/books/book">
You don't need msxsl:node-set() function here.
--
Oleg Tkachenko [XML MVP, XmlInsider]
http://blog.tkachenko.com
Sam Akiwumi
2004-03-05 15:58:45 UTC
Permalink
My intention was to get a handle on the node tree and iterate through it
picking out the individual elements. Do I need to use another function
to do this?

tx
Sam



*** Sent via Developersdex http://www.developersdex.com ***
Don't just participate in USENET...get rewarded for it!
Oleg Tkachenko [MVP]
2004-03-05 16:35:01 UTC
Permalink
Post by Sam Akiwumi
My intention was to get a handle on the node tree and iterate through it
picking out the individual elements. Do I need to use another function
to do this?
Who said you need any function (especially external function) to do such
trivial task? document() function returns nodeset, which you can iterate
over, that's it.
--
Oleg Tkachenko [XML MVP, XmlInsider]
http://blog.tkachenko.com
Sam Akiwumi
2004-03-06 02:12:53 UTC
Permalink
Thanks for the solution Chris.

Oleg, I was making changes to some legacy xsl, hence the nodeset() red
herring.

Tx
Sam



*** Sent via Developersdex http://www.developersdex.com ***
Don't just participate in USENET...get rewarded for it!

Chris Barber
2004-03-05 15:39:41 UTC
Permalink
You seem to have a stylesheet reference in the XML (not a problem in itself)
and are also using a document reference in the XSLT. I think it's the
document() reference that is failing, not the node-set extension. You don't
really need the document() function at all.

Simplify it to:

XML:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl"
href="C:\Projects\kmc.co.uk\e-commerce\Rules Engine\XSL
Stylesheets\Nodeset.xsl"?>
<books>
<book author="Michael Howard">Writing Secure Code</book>
<book author="Michael Kay">XSLT Reference</book>
</books>

XSLT:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:user="http://www.contoso.com">
<xsl:variable name="books" select="/"/>
<xsl:template match="/">
<authors>
<xsl:for-each select="msxsl:node-set($books)/books/book">
<author>
<xsl:value-of select="@author"/>
</author>
</xsl:for-each>
</authors>
</xsl:template>
</xsl:stylesheet>

Resultant transform gives:
<?xml version="1.0" encoding="UTF-16"?>
<authors xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:user="http://www.contoso.com">
<author>Michael Howard</author>
<author>Michael Kay</author>
</authors>

To remove the namespaces then use the following XSLT instead:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:user="http://www.contoso.com"
exclude-result-prefixes="msxsl user" >
<xsl:variable name="books" select="/"/>
<xsl:template match="/">
<authors>
<xsl:for-each select="msxsl:node-set($books)/books/book">
<author>
<xsl:value-of select="@author"/>
</author>
</xsl:for-each>
</authors>
</xsl:template>
</xsl:stylesheet>

Giving:
<?xml version="1.0" encoding="UTF-16"?>
<authors>
<author>Michael Howard</author>
<author>Michael Kay</author>
</authors>

As a further point, you don't even need the nodeset function anyway, just
use:

<xsl:for-each select="$books/books/book">

and should probably make use of templates. msxsl:nodeset is only used for
converting a RTF into a nodeset for enumeration. In your case, the variable
has already achieved this.

Final version is (no document ref, no variable, no nodeset conversion):

XML:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl"
href="C:\Projects\kmc.co.uk\e-commerce\Rules Engine\XSL
Stylesheets\Nodeset.xsl"?>
<books>
<book author="Michael Howard">Writing Secure Code</book>
<book author="Michael Kay">XSLT Reference</book>
</books>

XSLT:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- Start at the document root -->
<xsl:template match="/">
<authors>
<xsl:apply-templates select="/books/book/@author"/>
</authors>
</xsl:template>
<!--Process the author attributes of a book to output the author -->
<xsl:template match="book/@author">
<author>
<xsl:value-of select="."/>
</author>
</xsl:template>
</xsl:stylesheet>

Giving:
<?xml version="1.0" encoding="UTF-16"?>
<authors>
<author>Michael Howard</author>
<author>Michael Kay</author>
</authors>

Sorry it's a fairly long post with a few different versions. The last one
seems to be signifcantly more simple and doesn't rely on extensions. I think
Dimitre would term it as more 'fundamental'.

Chris.

"Sam Akiwumi" <***@kensington.co.uk> wrote in message news:***@TK2MSFTNGP11.phx.gbl...
Hi

I am trying to get the transform the following XML

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl"
href="C:\Projects\kmc.co.uk\e-commerce\Rules Engine\XSL
Stylesheets\Nodeset.xsl"?>
<books>
<book author="Michael Howard">Writing Secure Code</book>
<book author="Michael Kay">XSLT Reference</book>
</books>

Using the following XSL
----------
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:user="http://www.contoso.com">
<xsl:variable name="books"
select="document('file://C:\Projects\kmc.co.uk\e-commerce\Rules
Engine\XML\Untitled2.xml')"/>
<xsl:template match="/">
<authors>
<xsl:for-each select="msxsl:node-set($books)/books/book">
<author><xsl:value-of select="@author"/></author>
</xsl:for-each>
</authors>
</xsl:template>
</xsl:stylesheet>
---------------------------
I have created code in C# to do the transformation and I am using the
built-in XSLT Processor (implements the XSL Transformations (XSLT)
Version 1.0 recommendation).

Code
----------------------------
//Load the file to transform.
XPathDocument doc = new XPathDocument(xmlFile);

// Create a resolver with default credentials.
XmlUrlResolver resolver = new XmlUrlResolver();
resolver.Credentials = System.Net.CredentialCache.DefaultCredentials;

//Load the stylesheet
XmlDocument xsl = new XmlDocument();
xsl.Load(stylesheet);
XslTransform xslt = new XslTransform();
xslt.Load(xsl, resolver, this.GetType().Assembly.Evidence);

//Create an XmlTextWriter which outputs to the console.
StreamWriter outputWriter = new StreamWriter("C:\\Temp\\result1.xml");
XmlTextWriter writer = new XmlTextWriter(outputWriter);

//Transform the file and send the output to the console.
xslt.Transform(doc, null, writer, resolver);
----------------------------------

When I run the code, I get the an exception (below) which says the
Function 'msxsl:node-set()' has failed.

EXCEPTION
-----------------
InnerEx=System.Xml.Xsl.XsltException: Cannot convert the operand to
'Result tree fragment'.
at System.Xml.Xsl.XsltFunctionImpl.ToNavigator(Object argument)
at System.Xml.Xsl.FuncNodeSet.Invoke(XsltContext xsltContext,
Object[] args,
XPathNavigator docContext)
at System.Xml.XPath.XsltFunction.InvokeFunction(XPathNavigator qy,
XPathNodeI
terator iterator)
-----------------

Any ideas why this is happening? tx
Sam

*** Sent via Developersdex http://www.developersdex.com ***
Don't just participate in USENET...get rewarded for it!
Loading...