protected override table GetResult() {
return <table>
<tr>
<th>ID</th>
<th>Name</th>
<th>Company</th>
<th>Address</th>
<th>City</th>
<th>Zip</th>
<th>Phone</th>
</tr>
{GetCustomersByCountry(this.country)}
</table>;
}
It's still strongly typed (demos to come later), and it gets compiled completely down to IL via the Xen compiler. notice the curly braces following the closing < /tr> tag, that's an example of a code snippet XML Literal in Xen. The last part of Xen that i will touch on in this post is querying...the Xen way. there is quite a bit of useful information here, and one of the most exciting is SQL DML keywords (SELECT, DELETE, UPDATE, INSERT) becoming first class citizens as you will see. Querying takes on a new form in Xen. For now, it's being modeled after XQuery, but with a few changes:
no more "/", these will become "." to follow the paradigm we are all used to with C#/VB.NET/etc
0 based indexes instead of 1 based
XPath aggregates are supported (avg(), sum(), etc)
Queries are strongly typed, and mapped to the CLR
Xen/C# variables can be plugged directly (and typesafely) into queries (without all the messy "" and '')
of course, here is a short snippet demonstrating some of these (this also explains the red code in one of the first samples):
Book[] books = ...;
string name = "Joe Bloggs";
string* titles = books[author == name].title;
What this example does is select all of the books with the author name of "Joe Bloggs", then return this as a stream to the variable "titles" of type string*. the asterisk simply means a stream of strings, 0 or more values, a better definition is IEnumerator typed as "string". a good question is why not just return to an array of strings? you can't gaurantee the richer symantics of an array (indexing, counting, etc) over any query due to limitations of SQL itself.
we are at the last part of the equation in order to implement the ADO.NET programming problem, the SQL portion. the full set of SQL DML operations need to be implemented, and in it's prelimenary form, Xen will add two more; "Replace" and "Move" for XML design reasons (where in a tree you want to do these operations). here is a list of each, and their Xen implementation:
Select - select * from Customers where Zip == 98072
Update - update group.employee.salary *= 1.1;
Insert - insert group.employee[salary>100] before foo;
Replace - replace group.employee[salary>100].bonus with 10;
Move - move group.employee[salary>1000] after wdinc;
Delete - delete group.employee[salary>1000000];
I think they are pretty self explanatory, it's also worth noting that Xen isn't rebuilding these notions, it's simply a wrapper on top of the existing model that's already in place...why reinvent the wheel. here is an example of ADO.NET code, and it's corresponding Xen counterpart:
SqlCommand cmd = new SqlCommand("select *" +
+ " from orders"
+ " where Total > @threshold",
this.Connection);
cmd.Parameters.Add("@threshold").Value = threshold;
IDataReader r = cmd.ExecuteReader();
while (r.Read()) {
…
}
Becomes:
foreach (OrdersRow row in
(select * from orders where Total > threshold))
{
…
}
Again, the benefits should be pretty apparent just from glancing at the code. one of the final things i will touch on is XSLT in Xen. here is a short snippet of XSLT that has an embedded C# function in it to calculate the balance of a ledger and return it to the XSLT document:
<xsl:for-each select="Ledger/*">
<xsl:value-of select="user:Total(.))"/>
xsl:for-each>
<msxsl:script implements-prefix='user' language='C#'>>
decimal balance = 0;
void Total(XPathNodeIterator iter) {
XmlNode node = e.NextNode();
string s = node.SelectSingleNode("amount").InnerText;
decimal amount = Decimal.Parse(s);
if (node.Name == "deposit" || node.Name == "balance")
balance += amount;
else
balance -= amount;
return balance;
}
]]>
msxsl:script>>
One of the things about XSLT is that, while it certainly tries to be, it's not a general purpose programming language, so you will always run into those boundaries and end up in the classic ASP paradigm of embedding script into your XSLT docs if you need anything dynamic. here is the same code block implemented in Xen:
int position = 0;
foreach (Item c in ledger.child::*) {
if (c is Deposit || c is OpeningBalance) {
balance += c.amount;
} else {
balance -= c.amount;
}
yield {balance};
}
And again, the advantages should be pretty apparent. *note* if you are wondering what the "yield" statement does, check out some info on iterators in the v 2.0 release of C#, the statement does the exact same in this situation as it does for iterators.
So that's the end of the first part of my multi-post on Xen. This was meant to be purely an informative post, i am saving opinions for another time. also, the code examples in this post are meant to be informative only as no doubt the syntax will change drastically before Xen ever sees the light of the CLR. In a future post I will touch on how Xen may be implenting some of the new features of C# v 2.0 (we've seen iterators here, generics, etc are also tied in to Xen), as well as some more XPath information and some samples of what Xen can do to enhance existing applications. as always, comments are welcome (please note that i am not an XML guru). This is pretty revolutionary stuff, and it makes me remember why I chose to be a programmer in the first place.
- "Intro to Xen, Page 1/3"
- "Intro to Xen, Page 2/3"
- "Intro to Xen, Page 3/3"



