views:

41

answers:

2

Hello, I work on an xslt stylesheet, and I should receive as parameter two additional XML. I get an error when I use the node-set() method (from namespace ms, microsoft). The contents of the XML is correct. The parameters are send with classic ASP.

Here's the header and the call in xslt:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
     xmlns:ms="urn:schemas-microsoft-com:xslt"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
...
<xsl:param name="xmlPlanning"></xsl:param>
<xsl:variable name="myXml" select="ms:node-set($xmlPlanning)"></xsl:variable>
    <xsl:value-of select="ms:node-set($xmlPlanning)/*"/>

Here's the stack trace of the error:

[XsltException: Impossible de convertir l'opérande en 'fragment de l'arborescence résultat'.]
   System.Xml.Xsl.XsltOld.XsltFunctionImpl.ToNavigator(Object argument) +380943
   System.Xml.Xsl.XsltOld.FuncNodeSet.Invoke(XsltContext xsltContext, Object[] args, XPathNavigator docContext) +33
   MS.Internal.Xml.XPath.FunctionQuery.Evaluate(XPathNodeIterator nodeIterator) +292

[XPathException: Échec de la fonction 'ms:node-set()'.]
   MS.Internal.Xml.XPath.FunctionQuery.Evaluate(XPathNodeIterator nodeIterator) +347
   System.Xml.Xsl.XsltOld.Processor.RunQuery(ActionFrame context, Int32 key) +24
   System.Xml.Xsl.XsltOld.VariableAction.Execute(Processor processor, ActionFrame frame) +200
   System.Xml.Xsl.XsltOld.ActionFrame.Execute(Processor processor) +20
   System.Xml.Xsl.XsltOld.Processor.Execute() +82
   System.Xml.Xsl.XsltOld.Processor.Execute(TextWriter writer) +96
   System.Xml.Xsl.XslTransform.Transform(XPathNavigator input, XsltArgumentList args, TextWriter output, XmlResolver resolver) +68
   System.Xml.Xsl.XslTransform.Transform(IXPathNavigable input, XsltArgumentList args, TextWriter output, XmlResolver resolver) +43
   System.Web.UI.WebControls.Xml.Render(HtmlTextWriter output) +132

And here's the beginning of the xml I receive in parameter :

<?xml version="1.0" encoding="UTF-8"?>
<ArrayOfGenerationPlanningDesign xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://webservices.secureholiday.net/"&gt;
  <GenerationPlanningDesign>

What could be my problem ?

A: 

node-set() operates on Result Document Fragments (RDFs) only, but you give it a string, which is something entirely different (even if the string contents looks like XML).

What you must do is parse the string into XML. You can use an extension script for that. The following worked for me (tested with msxsl.exe on the command line), but if you don't want to use JScript you can use C# or any other supported language to do the same.

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:ms="urn:schemas-microsoft-com:xslt"
  xmlns:script="urn:my-scripts"
  exclude-result-prefixes="ms script"  
>
  <ms:script language="JScript" implements-prefix="script">
    <![CDATA[
    function stringToXml(str) {
      var xml = new ActiveXObject("MSXML2.DOMDocument.4.0");
      xml.async = false;
      xml.loadXML(str);
      return xml;
    }
    ]]>
  </ms:script>

  <xsl:param name="xmlPlanning"></xsl:param>

  <xsl:variable name="myXml" select="script:stringToXml(string($xmlPlanning))" />

  <xsl:template match="/">
    <xsl:value-of select="$myXml/*" /><!-- whatever -->
  </xsl:template>

</xsl:stylesheet>
Tomalak
I can't use this because i'm in classic Asp : i've make some test using .NET (wich explain my .net stack trace on my first post), but the final result have to be in classic asp.
Paul Rey-Camet
@Paul: I think you should try it before you say "I can't use this".
Tomalak
Sorry you're right. I've tried a moment your method, but i finaly opt for a concatenation in order to have only one XML. That solve my problems. Thank you very much for your help anyway!
Paul Rey-Camet
+1  A: 

In case the parameter you are passing is already a true nodeset (XPath navigator or XPathNodeIterator in .NET or IXMLDOMNodeList for MSXML), you don't need and must not use the ms:node-set() extension function. Simply remove the call to ms:nodeset().

In case it is a string that represents XML -- well it shouldn't! Parse this string to one of the allowable parameter types for a nodeset and only then invoke the transformation -- using the true node-set.

Dimitre Novatchev
+1 for the direct path. Better choice than parsing the strings in XSLT itself.
Tomalak