February 2009 Entries
XPath Query
There are many tutorials explaining the syntax's of  XPathQuery. What gets me confused sometimes is the understanding of the match and select statements of the templates. Here is a simple example. The XML file that we are going to query is:

School.xml

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="Apply.xslt"?>

<School>
  <title>The Xpath Exercise</title>
  <people>
    <teacher>
      <FirstName>Henry</FirstName>
      <age>45</age>
      <description>Henry will be the tutor</description>
     </teacher>
     <student>
      <FirstName>Jack</FirstName>
      <age>15</age>
      <description> is an American</description>
      <FoodPref picture="dolores_001.jpg">Sea Food</FoodPref>
    </student>
    <student>
      <FirstName>Sorensen</FirstName>
      <age>16</age>
      <description> is a swedish</description>
      </student>
  </people>
  <furniture>
    <chair>
      <name>revolving chair</name>
    </chair>
  </furniture>
</School>




So we have a direct child of  root element <School>. School has two  child elements called <people> and <furniture> People has child elements called teacher and student. Now we only want to show the students.Their first name and description.Here is the XSLT file that we are going to use.

Apply.xslt

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="1.0">

  <xsl:output method="html"/>

  <xsl:template match="/School">
    <html>
      <body bgcolor="#FFFFFF">
        <h1>What do we know about our students ?</h1>
        Here are some information <ul>
          <xsl:apply-templates select="people" />
        </ul>
      </body>
    </html>
  </xsl:template>
  <xsl:template match="people">
          <xsl:apply-templates select="student"/>
   </xsl:template>
  <xsl:template match="student">
    <li>
      <xsl:value-of select="FirstName"/>
      <xsl:apply-templates select="description"/>
    </li>
  </xsl:template>
 
</xsl:stylesheet>

The syntax for locating the direct child t of root node is /XML_ElementName. Lets look at the beginning of  our first template.
<xsl:template match="/School">
 This defines the execution context of the template.It means the scope is the School element and the selection defined in this template will take effect on any school element in the output.

Now comes the important part.
<xsl:apply-templates select="people" />
This tells us that inside the school element, only the contents of the people element are going to be shown,so we are filtering out <furniture> here.

In the next template, we are increasing the level of filtering. Here the context is defined as <xsl:template match="people">.So this template is going to be applied on any people element in the output.So this is obviously going to be invoked by the first template call, as the first template is returning people element.The selection criteria here is
   <xsl:apply-templates select="student"/>
So any people element will be showing ony the student elements inside it, leaving out the teacher element that we have.

In the third step, we define a template for the student element itself. Till now all our endeavour was targeted at outputting a student element. So now we define how much information of the student we are going to show and how we want to show it. We want to show it as list elements.
<xsl:apply-templates select="description"/>
So we want to show the description element of the student. We also want to show the value of the FirstName element.This can be done with .
 <xsl:value-of select="FirstName"/>

So if you open the School.xml file the output you get should be:

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati
How to refer a XSLT file in a XML Dcoment
Suppose You have a XML File Jungle.xml.

<?xml version="1.0"?>

<project>
  <title>The Xpath project</title>
<problems>
    <problem>
      <title>Initial problem</title>
      <description>We have to learn something about Location Path</description>
      <difficulty level="5">This problem should not be too hard</difficulty>
    </problem>
    <solutions>
      <item val="low">Buy a XSLT book</item>
      <item val="low">Find an XSLT website</item>
      <item val="high">Register for a XSLT course and do exercices</item>
    </solutions>
    <problem>
      <title>Next problem</title>
      <description>We have to learn something about predicates</description>
      <difficulty level="6">This problem is a bit more difficult</difficulty>
    </problem>
    <solutions>
      <item val="low">Buy a XSLT book</item>
      <item val="medium">Read the specification and do some exercises</item>
      <item val="high">Register for a XPath course and do exercices</item>
    </solutions>
  </problems>
</project>

You have an XSLT file called Jungle.xslt file.

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="1.0">

  <xsl:output method="html"/>

  <xsl:template match="/project">
    <html>
      <body bgcolor="#FFFFFF">
        <h1><xsl:value-of select="title" /></h1>
        Here are the titles of our problems: <ul>
        <xsl:apply-templates select="problems/problem" />
      </ul>
      </body>
    </html>
  </xsl:template>

<xsl:template match="problems/problem">
  <li><xsl:value-of select="title" /></li>
</xsl:template>

</xsl:stylesheet>

So how do you refer this xslt file in the xml file? Simple just add this one line under the <?xml version Tag just like this..

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="Jungle.xslt"?>

Now Open the xml file in IE without this stylesheet reference added and with added.You will see the difference.
  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati
WPF Two way databinding explained
Many get confused over the two way databinding concept. This is usually  done by implementing INotiyPropertyChanged interface.You can find many examples with INotiyPropertyChanged if you google for it.  Here I am presenting a very basic example of WPF databinding to show its advantages.

Create a WPF Application called "TwoWayDataBinding". You have app.xaml and Window1.xaml. Add one class called Customer to the project. The code for the class is bellow.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TwoWayDataBind
{
    class Customer
    {
        private string m_name;

        public string Name
        {
            get { return m_name; }
            set { m_name = value; }
        }
        private string m_State;

        public string State
        {
            get { return m_State; }
            set { m_State = value; }
        }
    }
}

We have two string  properties called  name and state in the customer class. We are going to use this class as the datasource for our  WPF form.

Now look at the XAML code for the Window1.xaml file. The explanations will follow.

<Window x:Class="TwoWayDataBind.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:myapp="clr-namespace:TwoWayDataBind"
    Title="Window1" Height="300" Width="300">
    <Window.Resources>
        <myapp:Customer x:Key="Cust2" Name="Hansen" State="Arizona"/>
    </Window.Resources>
    <Grid x:Name="Grid1"  DataContext="{StaticResource Cust2}">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <TextBlock Grid.Column="0" Grid.Row="0">Name:</TextBlock>
        <TextBlock Grid.Column="0" Grid.Row="1">State:</TextBlock>
        <TextBox x:Name="TextBox1" Grid.Column="1" Grid.Row="0" Text="{Binding Path=Name}"></TextBox>
        <TextBox x:Name="TextBox2" Grid.Column="1" Grid.Row="1" Text="{Binding Path=State}"></TextBox>
        <Button Grid.Column=" 1" Grid.Row="2"   Name="button1" Click="OnClicked">Control To Context</Button>
      
    </Grid>
</Window>

In the first  line the class Name for the Window1 form is specified.

Next, there are two XML namespace declarations. The first declaration maps the overall Windows Presentation Foundation (WPF) namespace as the default:

The second declaration maps a separate Extensible Application Markup Language (XAML) namespace, mapping it (typically) to the x: prefix.

Coming on to the next part, you can map XML namespaces to assemblies using a series of tokens within an xmlns prefix declaration, similar to how the standard WPF and XAML namespaces are mapped to prefixes.We are mapping a xml namespace myapp with the TwoWayDataBind Assembly . This will be  used in the next segment.

In the next section,we are declaring a resource dictionary. Microsoft defines these dictionaries as "Resource dictionaries that can be defined completely or partially in Extensible Application Markup Language (XAML) are typically created as a property element, and are typically on the root element for any individual page or for the application. Placing the resource dictionary at this level makes it easier to find from individual child elements in the page (or from any page, in the application case)". We are declaring a resource for  window element, so that all child elements of the window can access it. You can also define resources for page,grid and other elements. We used the xml namespace myapp, that we mapped to our application assembly section. We are accesing the customer class of the TwoWayBindingAssmbly with myapp:Customer. We are defining a key for the resource, which will be used for accessing it from other elements in the form. We are also specifying values for the two customer properties.

Next we define the grid element for the WPF form. Look at the part  DataContext="{StaticResource Cust2}. This is the important part for defining the databinding for our form. DataContext is a dependency property. It gets or sets the data context for an element when it participates in data binding. So are defining a datacontext for the Grid element here.We are defining the datacontext using the StaticResource. Static Resource provides a value for any XAML property attribute by looking up a reference to an already defined resource. That defined resource here is obviously Cust2, which is nothing but our customer class.

The Next 11 lines defines the form design xaml, as any wpf developer would find it  easy to understand. Coming to the part of our interest :

        <TextBox x:Name="TextBox1" Grid.Column="1" Grid.Row="0" Text="{Binding Path=Name}"></TextBox>
        <TextBox x:Name="TextBox2" Grid.Column="1" Grid.Row="1" Text="{Binding Path=State}"></TextBox>

   Here we are binding the text properties of the text boxes to the properties of the customer class. MSDN describes WPF databinding as "

To use WPF data binding, you must always have a target and a source. The target of the binding can be any accessible property or element that is derived from DependencyProperty—an example is a TextBox control's Text property. The source of the binding can be any public property, including properties of other controls, common language runtime (CLR) objects, XAML elements, ADO.NET DataSets, XML Fragments, and so forth. To help you get the binding right, WPF includes two special providers—the XmlDataProvider and the ObjectDataProvider."

The syntax we are using here is called attribute syntax. It condenses the data binding code inside of the Text attribute of the TextBox. Basically, the Binding tag gets pulled inside of the curly braces along with its attributes. "Path" is one of the Four components of Binding class. It gets or sets the path to the binding source property.  So here we are setting the two properties of  the customer class the the Binding source property of the textbox's text propety.

We have a button on the form and it has a click event method defined. Here is the code for the codebehind for the form.

Window1.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Data;



namespace TwoWayDataBind
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
           
        }

        private void OnClicked(object sender, RoutedEventArgs args)
        {
            Customer c1=Grid1.DataContext as Customer;
          
            TextBox1.Text = c1.State;
           
        }
      
    }
}

Now if you run the project  you will see.


So the textbox's are bound to the customer properties. We can see the values of the customer object in the texboxes.So this is one side of the databinding...the target object is getting update by the value of the data source. Now write something in the state textbox and click the button. What do you see? The Name textbox getting populated with the value of the State textBox.

If we look at the code for the button click:

Customer c1=Grid1.DataContext as Customer;
 TextBox1.Text = c1.State;

We are not assigning the new value to the customer class or datacontext. As we type  in the State textbox, the dataContext  is getting updated. So when we assign the datacontext's State value to the Name textbox, we see it gets populated with the new value that is entered. Isn't it just fantastic?





  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati
Your First Simple Basic Asp.net Workflow
When I tried to jump into the asp.net workflow platform, I found out there are really very few simple/basic examples available in the internet. Most articles deal with huge business concepts,utilizing different workflowservices, that can be really confusing for someone new to workflow development.Here I have tried a simple hello world Type of Asp.net Workflow..this is not bad for a startup.

The concept is really simple.You have a webpage default.aspx , with a textbox and a button. You enter an amount in the textbox and if the amount is more than 100, you are redirected to the credit.aspx and if less, to the debit.aspx. To start, Place the code from my previous post, into the application_start and application_end section of  your Global.asax page.

Add a sequential workflowLibrary  project to your solution.(my one is named workflowLibrary2).You see there is a sequential workflow  workflow1 added to the project. Drop a ifElseActivity from the Toolbox.


Now in the left ifElseactivity, set the condition property as codecondition and define the condition as ValidateAmount.Double clicking it will take you the codebehind for the workflow1.cs.Place 2 codeactivity objects on both the branches. I will come back to this later.

Now on the codebehind section of the workflow1.cs, rightclick-->insertsnippet-->other-->workflow-->WorkflowDependencyProperty. Like this you make two properties like below.

 public static DependencyProperty AmountProperty = DependencyProperty.Register("Amount", typeof(Int32), typeof(Workflow1));

        [DescriptionAttribute("Amount")]
        [CategoryAttribute("Amount Category")]
        [BrowsableAttribute(true)]
        [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
        public Int32 Amount
        {
            get
            {
                return ((Int32)(base.GetValue(Workflow1.AmountProperty)));
            }
            set
            {
                base.SetValue(Workflow1.AmountProperty, value);
            }
        }
        public static DependencyProperty ResultProperty = DependencyProperty.Register("Result", typeof(string), typeof(Workflow1));

        [DescriptionAttribute("Result")]
        [CategoryAttribute("Result Category")]
        [BrowsableAttribute(true)]
        [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
        public string Result
        {
            get
            {
                return ((string)(base.GetValue(Workflow1.ResultProperty)));
            }
            set
            {
                base.SetValue(Workflow1.ResultProperty, value);
            }
        }
The first property is integer and the second one string.

Now come back to the ifElseActivity Condition. We are just going to check if the amount entered is more than 100.

 private void ValidateAmount(object sender, ConditionalEventArgs e)
        {
            if (this.Amount > 100)
                e.Result = true;
        }
The conditionaleventArg e is evaluated here. If the condition is satisfied assign e.Result as true, so the activity associated with it will be executed. No condition is specified for the other branch, so it will just act as an else clause. Now define ExecuteCode property of the CodeActivity objects by  selecting  the ExecuteCode property, writing down the name of the method for it and doubleClicking it. For CodeActivity1 I am writing RedirectCredit and for CodeActivity2  RedirectDebit.


        private void RedirectCredit(object sender, EventArgs e)
        {
            this.Result = "Credit.aspx";
        }

        private void RedirectDebit(object sender, EventArgs e)
        {
            this.Result = "Debit.aspx";
        }

The two dependency properties that  I defined above are going to be used as parameters of the workflow. The easiest and simple way to pass parameters between the WorkFlow host application and the Workflow instance is to use Dictionary Objects collection. I am going to show how in the next section.

In the codebehind of the Default.aspx write code for the Button click event.

 protected void Button1_Click(object sender, EventArgs e)
    {
        InitiateWorkFlow();
    }
Define the InitiateWorkFlow method.

private void InitiateWorkFlow()
    {
        Dictionary<string, object> parameters = new Dictionary<string, object>();
        parameters.Add("Amount",Convert.ToInt32(TextBox1.Text));
        parameters.Add("Result", "");
        WorkflowRuntime wfRuntime = Application["WorkflowRuntime"] as System.Workflow.Runtime.WorkflowRuntime;
        wfRuntime.WorkflowCompleted += new EventHandler<WorkflowCompletedEventArgs>(wfRuntime_WorkflowCompleted);
        WorkflowInstance wi = wfRuntime.CreateWorkflow(typeof(WorkflowLibrary2.Workflow1), parameters);
        wi.Start();
        ManualWorkflowSchedulerService ss = wfRuntime.GetService<ManualWorkflowSchedulerService>();
        ss.RunWorkflow(wi.InstanceId);
        //HttpContext.Current.Session["WorkflowID"] = wi.InstanceId;
    }
Lets describe it. First we declare a Dictionary collection object  'parameters'. This is the parameter object that the host is going to use to pass on to the workflow. I add two parameters amount and result, to the collection.Then I declare a WorkflowRuntime Object and load it with the runtime object from the application object, that was created in the application_Start  event. I am also adding an eventhander for the WorkflowCompleted Event.Then the WorkFlowInstance is created and look how the parameters object is passed on to it in the CreateWorkflow method. The 2 params created here will be mapped on to the Dependency properties in the workFlow. Then the workflow instance is started.

Next, remember the   ManualWorkflowSchedulerService that we added to the WF Runtim, in the Application_start event. We retrieve that   ManualWorkflowSchedulerService by using the GetSerive method of the wfRuntime object. Then we execute the RunWorkFlow method of the   ManualWorkflowSchedulerService. We are doing this because this will use the delayactivity built in this newly developed   ManualWorkflowSchedulerService, so that once the host thread starts executing, it will stop for the workFlow thread to finish executing and resume itself again. This is synchronized execution of both the Host request and workflow runtime on the same thread.

Next we describe the WorkFlowCompleted Event.

 static void wfRuntime_WorkflowCompleted(object sender, WorkflowCompletedEventArgs e)
    {
        HttpContext.Current.Response.Redirect((string)e.OutputParameters["Result"]);  
    }
In this method, observe that the eventArgument is called WorkflowCompletedEventArgs. This argument e has a collection called Outputparametes which holds the Workflow paramater collection. So we can retrieve the value of the WorkFlow Parameter  'Result' and use it for our redirection of page.
  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati
Making sure Workflow Runtime has a single instance in the WebApplication Runtime
Source Code:MSDN
In previous versions, application used to get reference to Current workflowrutime by using codes like this:

WorkflowRuntime workflowRuntime=WorkflowRequest.Current.WorkflowRuntime;

But with 3.5 web applications use application object to store the workflowRuntime when the application starts and disposes of the runtime instance when the application stops. Global.asax file is used to hook the application_start and Application_End Event.

Here is how it is done:

void Application_Start(object sender, EventArgs e)
{
    System.Workflow.Runtime.WorkflowRuntime workflowRuntime =
        new System.Workflow.Runtime.WorkflowRuntime();

    System.Workflow.Runtime.Hosting.ManualWorkflowSchedulerService manualService =
        new System.Workflow.Runtime.Hosting.ManualWorkflowSchedulerService();
    workflowRuntime.AddService(manualService);
   
    workflowRuntime.StartRuntime();

    Application["WorkflowRuntime"] = workflowRuntime;          
}

void Application_End(object sender, EventArgs e)
{
    System.Workflow.Runtime.WorkflowRuntime workflowRuntime =
        Application["WorkflowRuntime"] as System.Workflow.Runtime.WorkflowRuntime;
    workflowRuntime.StopRuntime();
}

This workFlowRuntime instance remains in the application object as long as the webapplication handles requests.
Here is how you can how to retrieve this workflow runtime instance from the application object and star a workflow successfully.

protected void StartRuntime_Click(object sender, EventArgs e)
{
    WorkflowRuntime workflowRuntime = Application["WorkflowRuntime"] as WorkflowRuntime;
    ManualWorkflowSchedulerService manualScheduler =
        workflowRuntime.GetService(typeof(ManualWorkflowSchedulerService))
        as ManualWorkflowSchedulerService;

    WorkflowInstance instance = workflowRuntime.CreateWorkflow(
        typeof(ASPNetSequentialWorkflow));
    instance.Start();
    manualScheduler.RunWorkflow(instance.InstanceId);
}
  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati
Workflow Essentials
Source: MSDN
Things you should know before working on Workflow.

***   A workflow built on Windows Workflow Foundation is a component that requires an ad hoc runtime environment to function. The workflow runtime environment is represented by the WorkflowRuntime class. To host a workflow library, you create and configure an instance of the WorkflowRuntime class to operate on a particular workflow type. For performance reasons, you normally create the runtime environment only once in the application lifetime and make it serve all incoming requests. In a Windows Forms application, you initialize the workflow runtime in the form's constructor and destroy it with the form when the application shuts down.
  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati