C#

XSLT with Optional Extension Object

by Warlock on Dec.08, 2009, under .NET, C#, xml

Extension objects provide a convenient way to allow an XSL transform to interact with the outside world. They can also be used to offload computations that are difficult to express in XSL.

Recently, I ran into a scenario where I wanted to write an XSLT that would use an extension object to record some additional information about intermediate steps of the transform. The extension object was not required, however, and I wanted to leave it up to the user of the XSLT as to if they wanted to use the extension object.

The question then became how to conditionally execute calls to the extension object. Suppose you have the following extension object defined in C#:

public class FooExtensionObject
{
  private List<string> recordedValues = new List<string>();

  public void RecordValue(string val)
  {
    recordedValues.Add(val);
  }
}

Now suppose this extension object is used in the following XSLT:

<xsl:transform
        version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:foo="urn:FooExObj">
  <template match="/">
    ...
    <xsl:value-of select="foo:RecordValue(@bar)"/>
    ...
  </template>
</transform>

The extension object is supplied to the XSLT through the arguments:

XslTransform transform = new XslTransform();
transform.Load("SomeFile.xsl");

XsltArgumentList args = new XsltArgumentList();
FooExtensionObject aFoo = new FooExtensionObject();
args.AddExtensionObject("urn:FooExObj", aFoo);

XmlTextWriter myWriter = new XmlTextWriter("output.xml", null);

transform.Transform(xpathDoc, args, myWriter);

In the case where the extension object is not supplied, however, this XSLT will cause an error. To correct this issue, you can use the function-available function. Change the transform as follows:

...
<xsl:if test="function-available('foo:RecordValue')">
  <xsl:value-of select="foo:RecordValue(@bar)"/>
</xsl:if>
...

The conditional statement blocks out the use of the extension object when it does not exist. Unfortunately, you must do this where ever you wish to use the extension object.

Leave a Comment more...

XML Comments

by Warlock on Nov.24, 2009, under .NET, C#, Visual Studio

Today I was looking for a reference for the proper notation for the cref attribute of the <see cref="..."> C# XML comment tag, and after finding it, I thought I’d post it here for future reference.

The cref (code reference) tag is prefaced by a single character, then a colon, followed by the reference in question. The character defines what is being referenced, as defined by the table below.

Character Description
N Namespace
T Type (class, interface, struct, enum, delegate)
F Field (member variable, constant, etc)
P Property (including indexers and indexed properties)
M Method (including special methods like constructors – #ctor – operators, etc)
E Event
! Error string

The full reference for the prefixes is available here, with the full XML comment documentation available here. The Code Project also has an article on the topic.

1 Comment :, , , more...

.NET Order of Initialization

by Warlock on Nov.03, 2008, under .NET, C#

A while back I ran across this article about the dangers of calling a virtual method from the constructor of an inheritable class. The problem comes from the fact that if a new class is derived from the class with the virtual method call in its constructor (and overrides the virtual method), the base class will be calling the derived method on the child class, prior to the child class’ constructor running to completion.

As an extension to the code example to the aforementioned article, I’ve created an example that can a great interview question for understanding the order in which things are initialized. Consider the following set of classes (C#):

public class StringLogger
{
	public static string GetString(string s)
	{
		Console.WriteLine(s);
		return s;
	}
}

public class BaseType
{
	private string baseString
		= StringLogger.GetString("Base string");
	private static string baseStaticString
		= StringLogger.GetString("Base static string");

	static BaseType()
	{
		Console.WriteLine("Base static constructor");
	}

	public BaseType()
	{
		Console.WriteLine("Base instance constructor");
		DoSomething();
	}

	public virtual void DoSomething()
	{
		Console.WriteLine("Base DoSomething");
	}
}

public class DerivedType : BaseType
{
	private string derivedString
		= StringLogger.GetString("Derived string");
	private static string derivedStaticString
		= StringLogger.GetString("Derived static string");

	static DerivedType()
	{
		Console.WriteLine("Derived static constructor");
	}

	public DerivedType()
	{
		Console.WriteLine("Derived instance constructor");
	}

	public override void DoSomething()
	{
		Console.WriteLine("Derived DoSomething");
	}
}

There is a base class and a derived class, and a utility class that is used to log to the console when one of the string members of one of the other classes is initialized. Now consider creating an instance of the derived class:

public class MainClass
{
	public static void Main()
	{
		Console.WriteLine("Starting...");
		DerivedType d = new DerivedType();
		Console.WriteLine("Done.");
		Console.ReadLine();
	}
}

What will be the output to the console as the DerivedType class is instanciated?

(continue reading…)

1 Comment : more...

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!

Visit our friends!

A few highly recommended friends...