Wednesday, July 21, 2010

Elite For The iPhone And iPad

Unfortunately, I cannot post a link to the game here - I do want to bung down as much as I can and hopefully one day link to it...

I would love to see the Archimedes version of Elite - in my opinion the best version, because it had solid 3D graphics and very smooth controls - ported to the iPhone and iPad, possibly with the iPhone being able to act as a remote control for the iPad running the game.

However, first, a link to nostalgia:
The company Frontier, started by David Braben which now continues the Elite legacy:
Ian Bell's Elite FAQ:

Server Error With Virtual Directory

Trying to put a virtual directory under a web site in WinSrv2003, I hit this problem:

Server Error in '/TestSubSite' Application.


Configuration Error

Description: An error occurred during the processing of a configuration file required to service this request. Please review the specific error details below and modify your configuration file appropriately.

Parser Error Message: Could not load file or assembly 'SControls' or one of its dependencies. The system cannot find the file specified. (D:\web\testsite\web.config line 211)

Source Error:

Line 209:     Line 210:     Line 211:       Line 212:     Line 213:  

Source File: D:\web\testsite\web.config Line: 211




Fortunately, the answer is to wrap the system.web element in a location element, with the attributes path="." and inheritInChildApplications="false".

I've documented this fun on stackoverflow.com:

Thursday, July 15, 2010

How To Get DateTime In XSLT

It's actually quite easy, though definately not obvious, to perform a fairly standard =DateTime.Now operation in XSLT, even when using C# (the default Microsoft XSL parser is only on version 1.)

Here's the XSLT:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:my="urn:sample" extension-element-prefixes="msxml">

<msxsl:script language="JScript" implements-prefix="my">
function today()
{
return new Date();
}
</msxsl:script>
<xsl:template match="/">

Today = <xsl:value-of select="my:today()"/>

</xsl:template>
</xsl:stylesheet>

Here's the C#:

/// <summary>
/// Takes a string containing XML to be parsed and a string containing the the XSLT to do the parsing.
/// </summary>
public static string XSLTransformation(string xml, string xsl)
{
// create the readers for the xml and xsl
XmlReader reader = XmlReader.Create(new StringReader(xsl));
XmlReader input = XmlReader.Create(new StringReader(xml));

// create the xsl transformer
XslCompiledTransform t = new XslCompiledTransform(true);
XsltSettings settings = new XsltSettings(false, true);
t.Load(reader, settings, null);

// create the writer which will output the transformed xml
StringBuilder sb = new StringBuilder();
XmlWriterSettings tt = new XmlWriterSettings();
//tt.Encoding = new UTF8Encoding(false);
XmlWriter results = XmlWriter.Create(new StringWriter(sb)); //, tt);

// write the transformed xml out to a stringbuilder
t.Transform(input, null, results);

// return the transformed xml
return sb.ToString();
}

References:

Every Project Fails

Every project fails - you and I both know it - in two places: the Beginning and the End. Both of these, as Douglas Adams put it, are due to sloppy thinking. The first is because the full scope of the thing is not realised. The second is because the full scope of the thing is realised. The are known, in order, as "not writing the spec properly" and "feature creep". Often, the spec is not written properly because it is perceived to have been written properly or that it is someone else's job to write it out more, read: "flesh it out", also read: "passing the buck". Further, the feature creep happens not because due diligence is not done, but because discipline is not employed in keeping the extra features out. Even further, those features only come about because it's easier to think of new things when you've had time to think about the existing things. Give a project 3 months to progress and I guarantee that everyone on that project will have thought about some feature that wasn't in the original (even aged-) concept, simply because they've had more time to think.

What can be done about these? Some would say agile development is one (of many) approach, providing the time to define a concept but with development time allotted for later to deliberately increase the feature set as time, or units of the project, get completed. This is fine, as long as the wider scope of the project is realised at the start.

Wednesday, July 14, 2010

Google

How does Google work?...

Thursday, July 08, 2010

Parsing XML Into T-SQL Tables

Ok, some heavy SQLXML work here...

The aim was to make a query which would take any XML and list, in one table, all the elements, their attributes and their element and attribute values of the immediate child nodes of the root node. On top of that, each immediate child of the root had to be enumerated so it could be referenced properly when being inserted into another table/s.

Example input:

<root>
<date>07/07/10</date>
<start>07/02/10</start>
<m code="AL">
<Time>10:22</Time>
<Ask>1943.25</Ask>
<Open>1940.00</Open>
</m>
<m code="AA">
<Time>14:42</Time>
<Ask>143.05</Ask>
<Open>230.50</Open>
</m>
</root>

Example output:

ElementIndexParentElementFieldNameNodeTypeFieldValue
1mTimeelement10:22
1mAskelement1943.25
1mOpenelement1940.00
1mcodeattributeAL
2mTimeelement14:42
2mAskelement143.05
2mOpenelement230.50
2mcodeattributeAA

And finally, the SQL...

declare @xml XML
set @xml = 'YOUR XML HERE'

create table #t
(
rownum int,
xmlextract xml
)

-- populate the table with the child nodes of the root, if they have their own sub nodes
insert into #t
SELECT
row_number() over(order by getdate()) as 'RowNum',
pref.query('.') as XmlExtract
FROM
@xml.nodes('/*/*') AS extract(pref)
WHERE
pref.value('./*[1]', 'nvarchar(50)') IS NOT NULL

SELECT distinct rownum 'ElementIndex', ParentName 'ParentElement', FieldName, NodeType, FieldValue FROM
(
-- selects the attributes and their values from the xml
SELECT DISTINCT
rownum,
SubEl.SubElem.value('local-name(..)', 'nvarchar(50)') AS ParentName,
SubEl.SubElem.value('local-name(.)', 'nvarchar(50)') AS FieldName,
'attribute' as NodeType,
SubEl.SubElem.value('.', 'nvarchar(150)') AS FieldValue
FROM
#t
CROSS APPLY
xmlextract.nodes('//@*') AS SubEl(SubElem)
UNION
-- selects the inner element and their values from the xml
SELECT
rownum,
SubEl.SubElem.value('local-name(..)', 'nvarchar(50)') AS ParentName,
SubEl.SubElem.value('local-name(.)', 'nvarchar(50)') AS FieldName,
'element' as NodeType,
SubEl.SubElem.value('.', 'nvarchar(150)') AS FieldValue
FROM
#t
CROSS APPLY
xmlextract.nodes('/*/*') AS SubEl(SubElem)
) as tmp
ORDER BY ElementIndex, ParentElement, FieldName

drop table #t

However, for performance and tidy-up reasons, when using this code in a stored procedure, you may want to use a table variable. Here's the modified version:

declare @xml XML
set @xml = 'YOUR XML HERE'

declare @t table
(
rownum int,
xmlextract xml
)

-- populate the table with the child nodes of the root, if they have their own sub nodes
insert into @t
SELECT
row_number() over(order by getdate()) as 'RowNum',
pref.query('.') as XmlExtract
FROM
@xml.nodes('/*/*') AS extract(pref)
WHERE
pref.value('./*[1]', 'nvarchar(50)') IS NOT NULL

SELECT distinct rownum 'ElementIndex', ParentName 'ParentElement', FieldName, NodeType, FieldValue FROM
(
-- selects the attributes and their values from the xml
SELECT DISTINCT
rownum,
SubEl.SubElem.value('local-name(..)', 'nvarchar(50)') AS ParentName,
SubEl.SubElem.value('local-name(.)', 'nvarchar(50)') AS FieldName,
'attribute' as NodeType,
SubEl.SubElem.value('.', 'nvarchar(150)') AS FieldValue
FROM
@t
CROSS APPLY
xmlextract.nodes('//@*') AS SubEl(SubElem)
UNION
-- selects the inner element and their values from the xml
SELECT
rownum,
SubEl.SubElem.value('local-name(..)', 'nvarchar(50)') AS ParentName,
SubEl.SubElem.value('local-name(.)', 'nvarchar(50)') AS FieldName,
'element' as NodeType,
SubEl.SubElem.value('.', 'nvarchar(150)') AS FieldValue
FROM
@t
CROSS APPLY
xmlextract.nodes('/*/*') AS SubEl(SubElem)
) as tmp
ORDER BY ElementIndex, ParentElement, FieldName

References:

Tuesday, July 06, 2010

N00BS

SQLXML Gymnastics

Producing well-formed XML from SQL:
SELECT
ID,
Name as 'Names/FirstName',
Surname as 'Names/LastName'
FROM
Names
FOR XML PATH('person'), ROOT('people')
Converting XML into a table:

Input:
<Elements>
<Element>
<Index>1</Index>
<Type>3M</Type>
<Code>AL</Code>
<Time>1900-01-01T10:22:00</Time>
</Element>
<Element>
<Index>2</Index>
<Type>3M</Type>
<Code>AA</Code>
<Time>1900-01-01T19:00:00</Time>
</Element>
</Elements>
SQL:
SELECT
r.value('Index[1]', 'int') [Index],
r.value('Type[1]', 'nvarchar(50)') [Type],
r.value('Code[1]', 'nvarchar(50)') [Code],
r.value('Time[1]', 'datetime') [Time]
FROM
@content.nodes('/Elements/*') AS records(r)
Converting XML into a pivot table:

Input:
<Elements>
<Element>
<Index>1</Index>
<Type>3M</Type>
<Code>AL</Code>
<Time>1900-01-01T10:22:00</Time>
</Element>
<Element>
<Index>2</Index>
<Type>3M</Type>
<Code>AA</Code>
<Time>1900-01-01T19:00:00</Time>
</Element>
</Elements>
SQL:
SELECT
El.Elem.value('(Index)[1]', 'int') [Index],
SubEl.SubElem.value('local-name(.)', 'varchar(100)') AS 'Field Name',
SubEl.SubElem.value('.', 'varchar(100)') AS 'Field Value'
FROM
@content.nodes('/Elements/Element') AS El(elem)
CROSS APPLY
El.Elem.nodes('*') AS SubEl(SubElem)
WHERE
SubEl.SubElem.value('local-name(.)', 'varchar(100)') <> 'Index'
Produces:

IndexField NameField Value
1Type3M
1CodeAL
1Time1900-01-01T10:22:00
2Type3M
2CodeAA
2Time1900-01-01T19:00:00

Extracting attribute names (plus parent element name of each attribute):
SELECT
elem.value('local-name(..)', 'nvarchar(10)') AS 'Parent Name',
elem.value('local-name(.)', 'nvarchar(10)') AS 'Attribute Name',
elem.value('.', 'nvarchar(10)') AS 'Attribute Value'
FROM
@content.nodes('//@*') AS El(elem)
Extracting field names:
SELECT DISTINCT r.value('fn:local-name(.)', 'nvarchar(50)') FieldName
FROM @xml.nodes('/*/*') AS records(r)
Extracting nodes as XML:
SELECT
pref.query('.') as SomeXml,
FROM
@xml.nodes('/*/*') AS Content(pref)
Extracting nodes as XML with indices only if they have child nodes:
SELECT
row_number() over(order by cast(pref.query('.') as nvarchar(max))) as 'RowNum',
pref.query('.') as XmlExtract
FROM
@xml.nodes('/*/*') AS extract(pref)
WHERE
pref.value('./*[1]', 'nvarchar(10)') IS NOT NULL

Given:
DECLARE @content XML
SET @content =
'<people>
<person id="1" bimble="1">
<firstname bobble="gomble">John</firstname>
<surname>Doe</surname>
</person>
<person id="2" bimble="11">
<firstname bobble="zoom">Mary</firstname>
<surname>Jane</surname>
</person>
<person id="4" bimble="10">
<firstname bobble="womble">Matt</firstname>
<surname>Spanner</surname>
</person>
</people>'
Return:
-- All attributes with parent element name
SELECT
elem.value('local-name(..)', 'nvarchar(10)') AS 'Parent Name',
elem.value('local-name(.)', 'nvarchar(10)') AS 'Attribute Name',
elem.value('.', 'nvarchar(10)') AS 'Attribute Value'
FROM
@content.nodes('//@*') AS El(elem)

-- Inner element values (with index attribute)
SELECT
El.Elem.value('(@*)[1]', 'int') [Index],
SubEl.SubElem.value('local-name(.)', 'nvarchar(10)') AS 'Field Name',
SubEl.SubElem.value('.', 'nvarchar(10)') AS 'Field Value'
FROM
@content.nodes('/*/*') AS El(elem)
CROSS APPLY
El.Elem.nodes('*') AS SubEl(SubElem)

-- Second level element attributes (with index attribute)
SELECT
El.Elem.value('(@*)[1]', 'int') [Index],
SubEl.SubElem.value('local-name(.)', 'nvarchar(10)') AS 'Field Name',
SubEl.SubElem.value('.', 'nvarchar(10)') AS 'Field Value'
FROM
@content.nodes('/*/*') AS El(elem)
CROSS APPLY
El.Elem.nodes('@*') AS SubEl(SubElem)

-- Third level element attributes (with index attribute)
SELECT
El.Elem.value('(@*)[1]', 'int') [Index],
SubEl.SubElem.value('local-name(.)', 'nvarchar(10)') AS 'Field Name',
SubEl.SubElem.value('.', 'nvarchar(10)') AS 'Field Value'
FROM
@content.nodes('/*/*') AS El(elem)
CROSS APPLY
El.Elem.nodes('*/@*') AS SubEl(SubElem)

-- All element attributes and parent element name (with index attribute)
SELECT DISTINCT
El.Elem.value('(@*)[1]', 'int') [Index],
SubEl.SubElem.value('local-name(..)', 'nvarchar(10)') AS 'Parent Name',
SubEl.SubElem.value('local-name(.)', 'nvarchar(10)') AS 'Field Name',
SubEl.SubElem.value('.', 'nvarchar(10)') AS 'Field Value'
FROM
@content.nodes('/*/*') AS El(elem)
CROSS APPLY
El.Elem.nodes('//@*') AS SubEl(SubElem)
ORDER BY [Index]

External references:

I got the XML to paste properly by using this link to encode the XML into HTML:
  • http://centricle.com/tools/html-entities/

Friday, July 02, 2010

Server Application Unavailable

I'm hoping that this post will one day come under the tag heading "problem solved" but for now it's going to be "problems."

This damn thing seems to crop up whenever you least expect it. There's multiple solutions, none guaranteed.

Essentially, the initial problem with be a message in big red letter which says "Server Application Unavailable"

This is basically a message from IIS saying you don't have permissions to see the proper error.

In my particular case, giving the directory hosting the web app full security permissions to the ASPNET user identity and dropping the IIS Virtual Directory (tab) Application Protection to Low allowed the true error to be seen.

This was: Could not load file or assembly 'System.Web.Extensions, Version=2.0.....' etc.

At the same time, the Event Viewer also started showing: Failed to execute the request because the ASP.NET process identity does not have read permissions to the global assembly cache

I have also tried referencing the correct DLLs in the project references as I had tried to correct these links to the up-to-date DLLs, however they should have been pointing at a very specific location, brought in by SVN.

Ok, so the secret to this particular mess seems to have been "Make sure you're referencing the right DLLs."

Now the only problem is to solve the code issues in the controls!

Resources looked at so far include:

Adding And Subtracting Dates In T-SQL

This code will add 10 days to the current date:
@declare myDate datetime
set @myDate = (select dateadd(dd,10,getdate()))
select @myDate
This code will subtract one month from the passed in date:
@declare myDate datetime
set @myDate = (select dateadd(mm,-1,@dateArg))
select @myDate
Found at:

Thursday, July 01, 2010

Splitting Strings in T-SQL Using XML

Having this post:
And later finding this forum entry:
I have come up with my own SQL which does not require a function in order to take a series of pairs of integers and split them into a two-field result set:


Which when run on it's own, will output this:


The effect here is that a string passed in as a parameter can contain pairs (rows) of integers; each column in the rows being separated by ':' and each row being separated by ','.

This is aggregated into a single XML element, which can then be parsed into specific types in a result set (table) format.

Note: Sorry for the images, but blogger.com's online editor would not let me paste the XML source.

Event Firing Delegate Handlers For Basic Use Controls

Sometimes it's nice and tidy and simply easy to create a small user control which can listen fire events when it does something. This requires the use of delegates, the format of which escapes me every single time. Argh!

Anyway, here's an example:
public delegate void ChartSelected(int chartId);
public ChartSelected onChartSelected = null;
So the parent control or page would assign a method to the onChartSelected delegate to be fired when, in this case, a chart is selected:
selector.onChartSelected = MyEventMethod;
And the method fired when called would look like the delegate identifier:
private void ChartSelected(int chartId)
{
// do something
}
Of course, the control declaring the delegate has to fire the event at some point:
if (onChartSelected != null)
onChartSelected(someSelectedValue);