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.
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.
Determining SQL Server Version Number
by Warlock on Aug.03, 2009, under SQL
I’ve recently had to write some conditional SQL depending on which version of SQL Server I was running on.
This MSDN article shows that for modern versions of SQL Server, the following will get the full version number:
SELECT SERVERPROPERTY('productversion');
The problem with this is that it is in a string format (FYI you will need to cast it to VARCHAR), and it uses nested decimal notation (e.g. 10.0.1600.22 for SQL Server 2008). This format is very difficult to reason with, as what I am looking to do is conditionally execute SQL for SQL Server 2000 and for everything else execute some other SQL. I don’t care about minor revisions or service packs. To my knowledge, Microsoft does not provide any functions to work with nested decimals.
To make things easier, I constructed the following SQL to pull the major version number out of the string, convert it to an integer, and stick it in a variable:
DECLARE @MajorVersion int
SELECT @MajorVersion = CAST(substring(CAST(SERVERPROPERTY('productversion') AS VARCHAR), 0, Charindex('.', CAST(SERVERPROPERTY('productversion') AS VARCHAR))) AS int);
Messy, I know. If anyone else has a better method, please leave it in the comments.
Mapping Enums to custom strings in NHibernate
by Warlock on Jul.02, 2009, under .NET, Database
Many times when working with a legacy relation model and a newly developed C# object model that sits on top of the relational model, you may need to map enum values to/from arbitrary strings in the database using NHibernate.
For example, suppose you have a a work order object that three possible states: request, approved, denied. To represent this, you might use the following enum:
enum WorkRequestState
{
Request,
Approved,
Denied
};
But let’s assume that the legacy relational model has represented these values as strings: REQ, APR, DEN. You can’t change the values for the relational model, and you certainly don’t want to use these values in your enum because they are not as readable as the values shown above.
By default, NHibernate will automatically convert you enum to a string value that matches the name of the enum values if the table field a string, or it will convert to the integer value for the enum options if the table field is an integer.
To do the above custom mapping we must implement a custom NHibernate type.
First, create a new class that inherits NHibernate.Type.EnumStringType. In your constructor, pass the type of the enum you are handling, and the maximum number of characters that the enum values will be to the base class constructor:
class WorkRequestStateEnumStringType : NHibernate.Type.EnumStringType
{
public WorkRequestStateEnumStringType()
: base( typeof(WorkRequestState), 3)
{
}
...
}
Next, override the GetValue(...) method to map the enum value to the equivalent string.
public override object GetValue(object enm)
{
if( null == enm )
return String.Empty;
switch( (WorkRequestState)enm )
{
case WorkRequestState.Request : return "REQ";
case WorkRequestState.Approved : return "APR";
case WorkRequestState.Denied : return "DEN";
default : throw new ArgumentException("Invalid WorkRequestState.");
}
}
Override the GetInstance(...) method to map a string value to the equivalent enum value:
public override object GetInstance(object code)
{
code = code.ToUpper();
if( "REQ".Equals(code) )
return WorkRequestState.Request;
else if( "APR".Equals(code) )
return WorkRequestState.Approved;
else if( "DEN".Equals(code) )
return WorkRequestState.Denied;
throw new ArgumentException(
"Cannot convert code '" + code + "' to WorkRequestState.");
}
Finally, in the NHibernate mapping file, specify the property’s type as the derived EnumStringType class.
<class name="WorkRequest" table="work_request_table">
<property
name="Status"
column="status_field"
type="my.namespace. WorkRequestStateEnumStringType, MyAssembly" />
...
<class>
Note that when specifying this type, you must use the assembly-qualified name because the NHibernate code doing the mapping is in a separate assembly from the type you created.
This information has been derived from Jeremy Miller’s original post here.
Cocoa/UIKit BulbView
by Warlock on Jun.18, 2009, under Cocoa, iPhone
In my continuing saga to bring old-school displays to new-school (word?) devices, I’ve created a “bulb view” that displays characters in a grid of “lights”. The best way to describe it is probably just to see it:
Like previous LCD view you can set the colors for the lit & dim bulbs, but improved from the LCD view, you can use letters, numbers, and most punctuation/special characters. Again the rendering is done in pure Quartz2D.
The source, including demo apps for both the Mac and iPhone, can be found here. With this view I was smart and made it conditionally compile various parts so that it can be used on either the iPhone or the Mac, without needing separate files.
Conditional Compilation for iPhone
by Warlock on Jun.17, 2009, under Cocoa, iPhone
I’m working on a view right now that I want to be able to cross compile as either an NSView for the Mac, or a UIVIew for the iPhone. I originally wrote it for Leopard, but now I’m trying to add the precompiler directives to let it cross compile between the two platforms. A quick Google search didn’t reveal anything, here are the possible definitions you can use:
#define __MAC_10_0 1000 #define __MAC_10_1 1010 #define __MAC_10_2 1020 #define __MAC_10_3 1030 #define __MAC_10_4 1040 #define __MAC_10_5 1050 #define __MAC_10_6 1060 #define __MAC_NA 9999 /* not available */ #define __IPHONE_2_0 20000 #define __IPHONE_2_1 20100 #define __IPHONE_2_2 20200 #define __IPHONE_3_0 30000 #define __IPHONE_NA 99999 /* not available */
This definition comes from Availability.h located at /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.0.sdk/usr/include/Availability.h (for the iPhone 3.0 SDK).
Obviously, the __MAC_10_x is actually for the version of OSX, and the __IPHONE_x_x is for iPhone.
So, if you wanted to have code conditionally compile for the iPhone (assuming 3.0 SDK) you would do something like the following:
#ifdef __IPHONE_3_0
// iPhone
#import <UIKit/UIKit.h>
#else
// Mac
#import <Cocoa/Cocoa.h>
#endif
WPF Regular Expression Test Utility
by Warlock on Jun.16, 2009, under .NET, Software Development Tools, WPF
When working on .NET applications, I frequently need to test regular expressions I’m using in my code. There are many good utilities out there to test regular expressions, but most are web-based and rely on Javascript for regular expression processing, which lacks support for .NET’s named captures.
In response, I built the a regex test utility in WPF that has the following features:
- .NET syntax for regular expressions
- Supports named capture groups
- Gives real-time feedback (as you type) for the regular expression and the test input
The binary requires .NET 3.5 and is available here. The source can be found on GitHub here.
Also, for those of you working with .NET regular expressions, I’ve always found this site a great resource.
Vista-style Checkbox Images
by Warlock on May.27, 2009, under User Interfaces
The following picture contains all the images needed to make a tri-state checkbox on the web. It contains both hover and regular state for all checked modes except disabled. These come from screenshots from Windows Vista, so use at your own risk.
CGColorCreateGenericRGB Error on iPhone SDK 3.0
by Warlock on May.26, 2009, under Cocoa
While porting some Core Graphics/Quartz 2D code from the Mac to the iPhone, I ran across the following error:
error: 'CGColorCreateGenericRGB' is unavailable (declared at
/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.0.sdk/System/Library/Frameworks/CoreGraphics.framework/Headers/CGColor.h:31)
Looking in the header file in question (CGColor.h), I found the following:
/* Create a color in the "Generic" RGB color space. */
CG_EXTERN CGColorRef CGColorCreateGenericRGB(CGFloat red, CGFloat green,
CGFloat blue, CGFloat alpha)
CG_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA);
So the header file pretty much confirms what the error says; the function is not available on the iPhone.
After a little bit of looking through documentation, you just have to specify the color space manually and then give the components to the color. So the this:
CGColorCreateGenericRGB(0.90625, 0.80, 0.80, 1.0)
would become
CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB();
const CGFloat myColor[] = {0.90625, 0.80, 0.80, 1.0};
CGColorCreate(rgb, myColor);
CGColorSpaceRelease(rgb);
Cocoa LCD Screen View
by Warlock on May.25, 2009, under Cocoa
As part of an iPhone application I’m developing, I need a view that will display numbers/times in a way that will look like an old liquid crystal display calculator. I looked around at using various fonts to cover the same effect, but I wanted the look where you could slightly see the non-lit components of the display. As such, I delved into the mystical world of Quartz 2D.
MTILcdView allows you to set three parameters: the color for the “lit” crystals, the color for the “dim” crystals, and the text to be displayed. The view currently only supports displaying numbers plus the colon (”:”) per my needs, but it could easily be extended to display letters as well. The view decides the size of the digits to be displayed based on the height of the view, so for a given height you must adjust the width of the view to allow the needed number of characters to be displayed.
The source code for the Mac is available here: MTILcdView.h, MTILcdView.m. A complete demo application using the view can be retrieved from GitHub here.
The source code for the iPhone 3.0 SDK is available here: MTILcdView.h, MTILcdView.m (note that you must manually rename the files from MTILcdView1.{h|m} to MTILcdView.{h|m}). A complete demo application using the view can be retrieved from GitHub here.




