Friday, December 07, 2007

XMLSerialization with multiple XMLRoot attributes

I recently had to construct an object hierarchy in order to produce an xml config file for a third party application. A lot of the config file could be constructed from boiler plate xml, so I needed a way to load in sections. The section I wanted to load was for a config element which occurs someway down the heirarchy:

sometag
core
object_definitions
object_type type="myType" plugin="myPlugin"
config
moretags
moretags
moretags
config
object_type
sometag
[Haven't worked out how to escape tags quickly, so I've stripped the brackets]
The following code shows how I created a static method in my config class to load this.

8 ///

9 /// Allows definition of all UI properties

10 ///

11 [Serializable]

12 [XmlRoot("config")]

13 public class ConfigureUIObjectConfig : ObjectConfigBase

14 {

15 public static ConfigureUIObjectConfig LoadUIConfig(string filePath)

16 {

17 System.IO.StreamReader sr=null;

18 ConfigureUIObjectConfig conf;

19 try

20 {

21

22 XmlSerializer xs = new XmlSerializer(typeof(ConfigObjects.ObjectTypes.ConfigureUIObjectConfig));

23

24 sr = new System.IO.StreamReader(filePath);

25 conf = (ConfigureUIObjectConfig)xs.Deserialize(sr);

26 }

27 catch (Exception)

28 {

29 throw;

30 }

31 finally

32 {

33 if (sr!=null)

34 sr.Close();

35 }

36

37 return conf;

38 }


I invoke it from what is normally the root class in my hierarchy in the constructor:

52 public ConfigFile()

53 {

54 //Add default object types

55 ConfigureUIObjectConfig uiConf = new ConfigureUIObjectConfig();

56 ObjectType obj = new ObjectType();

57 //obj.Config = uiConf;

58 obj.Config = ConfigureUIObjectConfig.LoadUIConfig("DefaultUIConfig.xml");//uiConf;

59 obj.Plugin = "UiConfiguratorPlugin";

60 obj.Type = "ConfigureUI";

61 this.Core.ObjectDefinitions.ObjectTypes.Add( obj);

62

63 }



The key to getting this to work is to decorate the ConfigureUIObjectConfig class with the [XmlRoot("config")] attribute. If you do not do this you will get an exception:

System.InvalidOperationException: <config xmlns=''> was not expected.


This eluded me at first as I assumed that I could only mark one class with the XmlRoot attribute, however, it appears that this does not matter in this instance.

Wednesday, October 17, 2007

Typed DataSet NullValue behaviour

The default value for NullBehaviour in a typed DataSet in Visual Studio 2005 is to throw an exception. I recently needed to change this in a dataset containing 50 tables. Rather than edit it manually I edited the .xsd file using xml Notepad. I found a post on MSDN that indicated what needed changing:

msprop:nullValue="_empty" -- (Empty)

msprop:nullValue="_null" -- (Nothing)

msprop:nullValue="_throw" -- (Throw exception)

msprop:nullValue="_throw" is the default value and it is not persisted by default.



The xpath queries I used were:

--Find string columns with no null value prop
/xs:schema/xs:element/xs:complexType/xs:choice/xs:element/xs:complexType/xs:sequence/xs:element[(child::xs:simpleType/xs:restriction/@base='xs:string') and (not(@msprop:nullValue))]



and


--Find nodes where value exists and is not '_empty'

xs:schema/xs:element/xs:complexType/xs:choice/xs:element/xs:complexType/xs:sequence/xs:element[xs:simpleType/xs:restriction/@base='xs:string']/@msprop:nullValue[.!='_empty']

Wednesday, September 12, 2007

Conditional build events

In my current C# interop project, I unregister the existing COM dll using a pre-build event:

regasm /u $(TargetPath)

However, this fails if the file is not present (after a clean), so I use the following command to only unregister it if it is present.

path= $(TargetDir) for %f in ($(TargetFileName)) do C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\RegAsm.exe /u %f

Exposing COM events from .Net to Javascript in web browser

A lot has already been written about this so I won't repeat all the details here. These two links give a good guide to how to do it.

COM Interop Exposed - Part 2

HOW TO: Sink Managed C# Events in Internet Explorer Script

This post is about troubleshooting some common mistakes that may occur. The key thing to note is that if you fail to follow the steps listed in these articles:
  1. you will NOT get a compile time error
  2. you will NOT get an error when registering the component
  3. you will NOT get an error at runtime when you attach the event handler.
Mistakes that I made were:
  1. Did not put a Dispid attribute on the methods in my event interface.
  2. Had name mismatches between the events in my main class and the method names in my interface.
I'll add some test code here later.

Friday, September 07, 2007

COM component not registering properly

Related to my previous post, I was also having trouble getting the new .net COM object to register properly, even when I had removed all references to earlier versions. I had used:

>RegAsm assemblyName

but was unable to invoke the component in a web page. When I tried to examine it in OleView it initially seemed to be fine. However, when I tried to expand the class name node (under .Net category) I got the following error:

CoGetClassObject failed.
The system cannot find the file specified.

severity: SEVERITY_ERROR, facility: FACILITY_WIN32 ($80070002)

Registering it with:

>RegAsm assemblyName /codebase

fixed the issue

Regasm /u not working

I had a strange problem when trying to unregister a COM visible .Net component recently. I had built and registered several versions but when I tried to unregister them I could still see them listed when using OleView. It turns out that the command:

RegAsm /u assemblyName

will only remove the entries that match the version number of your assembly. If you have been incrementing the version number of your component and registering the new one without unregistering the previous version then you will end up with entries for each version. To clear them out you can just set the version number of the assembly, compile it and then unregister it with RegAsm. Do this for each version that you need to unregister.

Monday, July 23, 2007

What card are you?


You are The Hierophant


Divine Wisdom. Manifestation. Explanation. Teaching.


All things relating to education, patience, help from superiors.The Hierophant is often considered to be a Guardian Angel.


The Hierophant's purpose is to bring the spiritual down to Earth. Where the High Priestess between her two pillars deals with realms beyond this Earth, the Hierophant (or High Priest) deals with worldly problems. He is well suited to do this because he strives to create harmony and peace in the midst of a crisis. The Hierophant's only problem is that he can be stubborn and hidebound. At his best, he is wise and soothing, at his worst, he is an unbending traditionalist.


What Tarot Card are You?
Take the Test to Find Out.

Tuesday, May 22, 2007

Nice post at A very British Dude on the evils of socialism. Has this youTube video on the evils of communism:


Monday, May 14, 2007

Golden compass

There is a promotion site for the forthcoming film The Golden Compass which is the american name for the book The Northern Lights, the first in Philip Pullman's trilogy "His Dark Materials". They have a short personality test there which then assigns you a Daemon. You can then email a link to it to let your friends answer the same questions about you and see if your Daemon changes. Mine was initially a chimpanzee so I'll email a few people and see if it changes..

Sunday, May 13, 2007

Friday, May 11, 2007

Thursday, May 10, 2007

Prescient

The following passage is from the introduction of the Rapstone Chronicles by John Mortimer:

The discovery that has struck the Titmuss philosopy and left it badly holed is that caring for the environment is quite inconsistent with the free-market economy. Green and true-blue are colours that don't, unfortunately, mix. Preserving the countryside, protecting the woodlands, concern for the ozone layer, all demand levels of government intervention unthinkable in the heady days of victory over the miners and the Falklands War. The high spring of laissez-faire economics is over, the bloom is gone and, such is the nature of politics, with the bloom goes Titmuss.

Who will take his place? It seems likely that Conservatism in the Titmuss mould is now out of style, and his successors may be those prepared to revert to the old consensus days of Butler and Harold Wilson. But what of the left? If free-market Toryism has taken a beating it's as nothing to what recent events in Europe have done to the dreams of the Reverend Simcox. The Labour Party seems to have achieved its huge rise in the opinion polls by freeing itself from what are seen as the tentacles of a Socialist octupus. So what is the new, up-and-coming Labour M.P. going to be like? No doubt he will have extinguished the dear old Trades Union dinosaur. Unquestionably he will be outspoken, quick-witted, with a talent for P.R. and a complete freedom from class distinctions. He will, of course, be wearing a blue suit with a discreet tie, own a car phone and a word processor and believe in free enterprise in a mixed economy. Is the stage set, after the next election, for the emergence of the first Labour Titmuss? Whatever happens, of one thing there is no doubt, British politics will remain a fertile ground for comedy.


John Mortimer 1991

Tuesday, April 10, 2007

Shameful

In the end, every great power is as great as its credibility, and the only consolation after these last two weeks is that Britain doesn't have much more left to lose.

Ouch. I tried to convince myself that the decision to allow the 15 to give interviews was part of a cunning strategy. Then I saw this post. I am utterly appalled.

Monday, April 09, 2007

Goodbye Magna Carta article in the Times about the ridiculous anti protest legislation brought in by this government. I was rather ashamed to read the following:

Twenty miles from London, along the Thames, you will find a field opposite an island in the river. The field contains a monument erected by the American Bar Association. In the field next to it there is a memorial garden to John F Kennedy commemorating his role in the civil rights movement. Why on earth, you may imagine, are there American monuments in fields by the Thames? There are no other monuments. There is nothing to commemorate anything British.

Perhaps an important figure in American history was born there? Nope. The site is far more important to the American people than that. On that unmarked island in 1215 something was written down that more than 500 years later became the fifth amendment of the American Bill of Rights. “No freeman shall be taken, imprisoned . . . or in any other way destroyed . . . except by the lawful judgment of his peers, or by the law of the land. To no one will we sell, to none will we deny or delay, right or justice.”

Contrast this with the way we seem to have taken it for granted and allowed our freedoms to be eroded. At least the guys mentioned in the article are doing something about it.

Tuesday, April 03, 2007

Your Personality Profile

You are elegant, withdrawn, and brilliant.
Your mind is a weapon, able to solve any puzzle.
You are also great at poking holes in arguments and common beliefs.

For you, comfort and calm are very important.
You tend to thrive on your own and shrug off most affection.
You prefer to protect your emotions and stay strong.

My first question on asktom

Yay! My first question has been answered on asktom.

Monday, March 26, 2007

A common requirement when importing data into a table is to log any errors which occur due to constraint violation. This often leads to people processing data in a Cursor FOR LOOP and doing one insert at a time so that they can catch and log the error:

BEGIN
FOR source_rec IN (SELECT * FROM all_objects a)
LOOP
BEGIN
INSERT INTO t1
(col1
,col2
,col3)
VALUES
(source_rec.owner
,source_rec.object_name
,source_rec.subobject_name);
EXCEPTION
WHEN OTHERS THEN
--log error using PLVISION
plvexc.recngo;
END;
END LOOP;
END;

Another option is to use the EXCEPTIONS INTO clause of ENABLE constraint:
DECLARE
l_exc_count INTEGER;
BEGIN
--Disable unique constraint
EXECUTE IMMEDIATE 'ALTER TABLE t1 DISABLE CONSTRAINT UNQ_CONST1';
--Copy data (inc duplicates) from source table
INSERT INTO t1 (SELECT * FROM t2);
--The EXCEPTIONS table can be created using $ORACLE_HOME/rdbms/admin/utlexcpt.sql.
EXECUTE IMMEDIATE 'ALTER TABLE t1 ENABLE CONSTRAINT UNQ_CONST1 EXCEPTIONS INTO EXCEPTIONS';
--If constraint is violated it will still be disabled at this point
SELECT COUNT(1) INTO l_exc_count FROM t3;
IF l_exc_count > 0
THEN
--Copy invalid rows to errors table
EXECUTE IMMEDIATE 'CREATE TABLE errors_tab as SELECT * FROM t1,exceptions e where t1.rowid=e.row_id';

DELETE FROM t1
WHERE ROWID IN (SELECT minrid
FROM (SELECT object_id
,MIN(e.row_id) minrid
FROM EXCEPTIONS e
,t_dups t
WHERE t.ROWID = e.row_id
GROUP BY object_id));
END IF;
END;

Cool new feature in Oracle 10gR2 is the LOG ERRORS clause

Comment at asktom had the following:

insert /*+ APPEND */ into t select * from t2
LOG ERRORS REJECT LIMIT UNLIMITED;

Further details here

Friday, March 16, 2007

Record Exists

Copied from some tips put together by Chris Rudd, ultimately sourced from Steven Feuerstein
/*
Note that the following shows three ways of checking if a record exists which have very similar response times, one way (implicit cursor) which is bad, and a fifth way
( select count(*) ) which is a VERY BAD THING and will result in broken fingers for anyone found using it!
*/
SET VERIFY OFF
@ssoo
DECLARE
/* Different approaches to answering "at least one?" */
CURSOR empcur
IS
SELECT employee_id
FROM employee_big WHERE department_id = &&secondparm;
v NUMBER;
b BOOLEAN;
BEGIN
plvtmr.set_factor (&&firstparm);
plvtmr.capture;
FOR i IN 1 .. &&firstparm
LOOP
BEGIN
SELECT employee_id INTO v FROM employee_big
WHERE department_id = &&secondparm;
b := TRUE;
EXCEPTION
WHEN NO_DATA_FOUND THEN b := FALSE;
WHEN TOO_MANY_ROWS THEN b := TRUE;
END;
END LOOP;
PLVtmr.show_elapsed ('Implicit');

plvtmr.capture;
FOR i IN 1 .. &&firstparm
LOOP
OPEN empcur;
FETCH empcur INTO v;
b := empcur%FOUND;
CLOSE empcur;
END LOOP;
PLVtmr.show_elapsed ('Explicit');

plvtmr.capture;
FOR i IN 1 .. &&firstparm
LOOP
SELECT COUNT(*) INTO v
FROM employee_big WHERE department_id = &&secondparm;
b := v > 0;
END LOOP;
PLVtmr.show_elapsed ('COUNT');

/* Ohio OUG Contributions.... */
plvtmr.capture;
FOR i IN 1 .. &&firstparm
LOOP
SELECT COUNT(1) INTO v
FROM employee_big WHERE department_id = &&secondparm
AND ROWNUM <> 0;
END LOOP;
PLVtmr.show_elapsed ('COUNT ROWNUM<2'); department_id =" &&secondparm);"> @atleastone 1000 20
Implicit Elapsed: .45 seconds. Factored: .00045 seconds.
Explicit Elapsed: .12 seconds. Factored: .00012 seconds.
COUNT Elapsed: 2.21 seconds. Factored: .00221 seconds.
COUNT ROWNUM<2> @atleastone 20000 20
Implicit Elapsed: 8.06 seconds. Factored: .0004 seconds.
Explicit Elapsed: 2.46 seconds. Factored: .00012 seconds.
COUNT Elapsed: 42.21 seconds. Factored: .00211 seconds.
COUNT ROWNUM<2 Elapsed: 2.42 seconds. Factored: .00012 seconds.
EXISTS Elapsed: 2.63 seconds. Factored: .00013 seconds.

* /

END;
/

Thursday, March 08, 2007

Ask Tom "Hierarchical query"

Ask Tom "Hierarchical query"

Nice bit in follow up comments about collapsing rows using analytics.

Tuesday, February 20, 2007

Mr Eugenides: Menteurs

I'm not sure why the mendacity of this government still causes me to burst a blood vessel every now and then but this is extraordinary:

Mr Eugenides: Menteurs

Tuesday, February 13, 2007

Bad science - Gillian McKieth gets fisked

Ben Goldacre has a great piece in today's Guardian where he comprehensively demolishes the scientific pretensions of Gillian McKeith, who presents You are what you eat on Channel 4.

"McKeith is a menace to the public understanding of science. She seems to misunderstand not nuances, but the most basic aspects of biology - things that a 14-year-old could put her straight on. She talks endlessly about chlorophyll, for example: how it's "high in oxygen" and will "oxygenate your blood" - but chlorophyll will only make oxygen in the presence of light. It's dark in your intestines, and even if you stuck a searchlight up your bum to prove a point, you probably wouldn't absorb much oxygen in there, because you don't have gills in your gut. In fact, neither do fish. In fact, forgive me, but I don't think you really want oxygen up there, because methane fart gas mixed with oxygen is a potentially explosive combination. Future generations will look back on this phenomenon with astonishment."

hat tip to Tom Coates and the poor little greek boy.