Jump to content

AddExtensionObject, Hashtable and XSLT


Wing

Recommended Posts

Hi there,I try to pass the hashtable objects to XSLT using AddExtensionObject. I try to use "get_[PropertyName]()" method, it works on other properties, but not "this[object key]" in hashtable.In C#:private Hashtable ht = new Hashtable();Form form = new Form();form.type = "text";ht.add(form); XsltArgumentList xslArg = new XsltArgumentList();xslArg.AddExtensionObject("ext:ext", ht);In xslt:I tried to use "get_ht['key']", returns me nothing. If I try to use "get_ht['key']()", give me an error message, says "Expected end of the expression, found '('. ...ext:get_ht['key'] -->(<-- )"Also, how can I call a method like <xsl:value-of select="ext:get_ht[@Key].get_Type()" />, a object in the hashtable, which has a "Type" property? It will return me an error: "Expected end of the expression, found '.'. ...ext:get_ht[@Key] -->.<-- get_Type()"...By the way, how can I use "xsl:for-each" for "get_Keys()" method? <xsl:for-each select ="ext:get_Keys()"> returns an error message as "Expression must evaluate to a node-set."Thanks a lotWing

Link to comment
Share on other sites

What does ext:get_Keys() return? As noted by the error message, you can't use it unless it returns a node set. If you're able to value it off, chances are it's a simple string.As for the ext:get_ht() method, it seems it could be a syntax error. After all, "[]" mean predicates in XPath, and an expression isn't expected to start right after one. Try ext:get_ht('key') instead (and ext:get_ht(@Key).get_Type() respectively).

Link to comment
Share on other sites

get_Keys() should returns a Collection of Keys from the hashtable. They will be a set of strings. I am not sure how to make them to a node set.I tried ext:get_ht('key'), returns me an error message: " 'get_ValidationFields()' is an unknown XSLT function."...If I changed "ext:get_ht[@Key].get_Type()" to "ext:get_ht(@Key).get_Type()", it still returns me the same error message: "Expected end of the expression, found '.'. ...ext:get_ht[@Key] -->.<-- get_Type()"... It doesn't seem like the ".".Does "[", "]" and "." can be instead somehow in XSLT?Thanks a lotWing

Link to comment
Share on other sites

The problem is all of those have another meaning in XPath, and inherently, in XSLT. "[" and "]" encompass a predicate, and "." can be a part of an element's name, a decimal separator in a number or... I'm not sure what. So, when you have "ext:get_ht['key']", you're really requesting the ext:get_ht element at the current XPath context (as far as the predicate goes - a simple string would always evaluate to true, so it's like you have nothing).There are no objects in XPath, and thus function().something() is not a valid construction. You'll have to resrtict yourself as to not use objects. Arrays are also non-existent, but there should be some way in C# by which you can map them into node-sets, as node-sets are just that - an array of XPath nodes (and inside each node there can be another node-set or a string, sometimes easily translatable into a number or a boolean).I'm not aware of the XSLT processor API you're using, but bottom line is you must manually translate C# functions into XPath functions, and XPath functions can only return node-sets, strings, numbers or booleans. If the method returns an array or object, you'll have to manually create another function that turns the other function's output into one of the XPath types.

Link to comment
Share on other sites

this may work for you, I found the trick to be to add the hashtable in the constructor for the class rather than try and pass it through as a object. I then invoke the getht method passing it a key value. At this time I hard-wired it just to get it working, but it may be enough to get you kick started.NET console app code

using System;using System.Collections;using System.Collections.Generic;using System.Text;using System.IO;using System.Xml;using System.Xml.XPath;using System.Xml.Xsl;namespace ConsoleApplication5{		class Program		{				static void Main(string[] args)				{						XslCompiledTransform xslt = new XslCompiledTransform();						xslt.Load("XSLTFile1.xslt");						XPathDocument doc = new XPathDocument("XMLFile1.xml");						XsltArgumentList xslArg = new XsltArgumentList();						Hashtable myHash = new Hashtable();						myHash.Add("1", "test1");						myHash.Add("2", "test2");						ht myht = new ht(myHash);						xslArg.AddExtensionObject("ext:ht", myht);						xslt.Transform("XMLFile1.xml", xslArg, XmlWriter.Create("output.xml"));				}				public class ht				{						Hashtable hh;						public ht(Hashtable ht)						{								hh = ht;						}						public string getht(string key)						{								return hh[key].ToString();						}				}		}}

XSLT File

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  xmlns:myHT="ext:ht">	<xsl:template match="/">		<top>			<xsl:value-of select="myHT:getht('1')" />		</top>	</xsl:template></xsl:stylesheet>

The content of XML file is not used here, but here it is for this example

<xml>	</xml>

Resulting Output file

<?xml version="1.0" encoding="utf-8"?><top xmlns:myHT="ext:ht">test1</top>

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...