This is all being run on an ASPX page.
What I'm attempting to do is to pass a node into some C# code, and use that to get a child node depending on the value of a second parameter.
When I pass in the node, I am not getting an XmlNode, nor an XmlDocument, XmlNodeList, etc.
I finally set the data type to Object and had it return GetType().ToString() and it claims the data type is System.Xml.XPath.XPathQueryIterator... yet XPathQueryIterator doesn't even show up in my (Visual Studio) list under XPath. The closest I could come up with that didn't complain about a wrong data type was XPath.XPathNodeIterator... but I can't find a way to get an XmlNode from that.
If I use XmlNode or XmlDocument I get the error: Cannot convert the operand to 'Result tree fragment'.
If I use XmlNodeList I get the error: Object type cannot be converted to target type.
** What I want is to be able to get an XmlNode so that I can do a SelectSingleNode() on it. How can I do this?
Here's a trimmed down copy of my XSLT code that is run on an ASPX page:
- - - - -
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:cs="C#">
<msxsl:script language="C#" implements-prefix="cs">
<![CDATA[
private string MyCSharpFunction(Object Param1, string Param2)
{ // I want to be able to get Param1 as an XmlNode
return Param1.GetType().ToString();
}
]]>
</msxsl:script>
<xsl:variable name="NodeToPassIn" select="document('MyExternalFile.xml')/RootNode" />
<xsl:template match="/RootNode">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="SomeNode">
<xsl:choose>
<xsl:when test="@someAttribute != ''">
<a target="_blank" href="{cs:MyCSharpFunction($NodeToPassIn, @someAttribute)}"><xsl:copy-of select="."/></a>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
- - - - -
ASPX Page:
<asp:Xml id="MyXml" runat="server" DocumentSource="SomeXmlFile.xml" TransformSource="TheAboveXslFile.xsl" />
--
Greg Collins [InfoPath MVP]
Please visit: http://www.InfoPathDev.com
Greg Collins [InfoPath MVP] wrote:
> I've run into a problem... I have an XSLT file that needs to get a
> value that is more complex than can be done in XSLT as the results
> will vary greatly depending on a second node value.
>
> This is all being run on an ASPX page.
>
> What I'm attempting to do is to pass a node into some C# code, and
> use that to get a child node depending on the value of a second
> parameter.
>
> When I pass in the node, I am not getting an XmlNode, nor an
> XmlDocument, XmlNodeList, etc.
The XPath/XSLT data model is different from the DOM data model and in
.NET there are certainly different classes and interfaces used so forget
about XmlNode and its subclasses for that task.
> <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0"
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
> xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:cs="C#">
>
> <msxsl:script language="C#" implements-prefix="cs"> <![CDATA[ private
> string MyCSharpFunction(Object Param1, string Param2) { // I want to
> be able to get Param1 as an XmlNode return
> Param1.GetType().ToString(); } ]]> </msxsl:script>
>
> <xsl:variable name="NodeToPassIn"
> select="document('MyExternalFile.xml')/RootNode" />
>
> <xsl:template match="/RootNode"> <xsl:apply-templates/>
> </xsl:template>
>
> <xsl:template match="SomeNode"> <xsl:choose> <xsl:when
> test="@someAttribute != ''"> <a target="_blank"
> href="{cs:MyCSharpFunction($NodeToPassIn,
> @someAttribute)}">
XSLT 1.0 nows primitive types like number, string, boolean and then only
node sets and result tree fragments as object types.
Here are the docs that explain the .NET equivalent:
<http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemXmlXslXslTransformClassTopic.asp>
The table in there about script in XSLT lists:
W3C Type Equivalent .NET Class
String (XPath) System.String
Boolean (XPath) System.Boolean
Number (XPath) System.Double
Result Tree Fragment (XSLT) System.Xml.XPath.XPathNavigator
Node Set (XPath) System.Xml.XPath.XPathNodeIterator
Your script functions will get arguments of those types and need to
operate with the APIs defined for those types:
<http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemXmlXPathXPathNavigatorClassTopic.asp>
<http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemXmlXPathXPathNodeIteratorClassTopic.asp>
--
Martin Honnen --- MVP XML
http://JavaScript.FAQTs.com/
I can only use XPathNodeIterator, as XPathNavigator is not allowed. It took a little playing, but here's how it worked:
Param1.MoveNext();
System.Xml.XPath.XPathNodeIterator Node = Param1.Current.Select(XPath);
Node.MoveNext()
return Node.Current.Value;
Wow! What a convoluted mess! It is incredible how painful that was... not very intuitive at all. But at least I got it working!
Thanks, Martin, for your help... it got me digging around a bit more.
--
Greg Collins [InfoPath MVP]
Please visit: http://www.InfoPathDev.com
"Martin Honnen" <maho...@yahoo.de> wrote in message news:O6GsfRcx...@TK2MSFTNGP10.phx.gbl...
Greg Collins [InfoPath MVP] wrote:
> I can only use XPathNodeIterator, as XPathNavigator is not allowed.
As said, it depends on the XPath/XSLT type that is passed to a function,
if you pass in a node set then you use XPathNodeIterator, but if you
pass in a result tree fragment then you use XPathNavigator.
Result Tree Fragment (XSLT) System.Xml.XPath.XPathNavigator
Node Set (XPath) System.Xml.XPath.XPathNodeIterator
--
For my interest what did you need that couldn't be done via pure XSLT?
I am compiling a few use cases for scripting following some questions from
Microsoft.
--
Joe
"Greg Collins [InfoPath MVP]" <Greg.Collins_AT_InfoPathDev.com> wrote in message
news:uaRFIwcx...@TK2MSFTNGP14.phx.gbl...
<Template id="abcd" url="http://someserver.foo/folder/{0}/{1}#{2}"/>
or something like that. Each url might have a different number of parameters...
Now your probably saying... well you can do this in XSLT... just use an xsl:choose construct and a series of translate() functions. True. You can do it that way. But I didn't want to have to hastle with all of those there.
Instead I just create a single link:
<a target="_blank" href="{cs:TemplateLink($Templates, @url)}"><xsl:copy-of select="."/></a>
This way my XSL is cleaner and I can use C#'s string.Format() function. I can also do other comlplex things when filling in the parameters as C# is a lot more powerful than the few functions you get in XSLT.
Anyway... that was the idea behind it. I still don't understand why I can't get an XmlNode object back from an XPathNodeIterator -- I can get the node value, just not the node itself -- but at least it is working now.
--
Greg Collins [InfoPath MVP]
Please visit: http://www.InfoPathDev.com
"Joe Fawcett" <joefa...@newsgroups.nospam> wrote in message news:#HuqyApx...@TK2MSFTNGP09.phx.gbl...