Wednesday, July 11, 2012

XmlDocument Class ImportNode() method

The XmlDocument.ImportNode() method is probably one of the most misunderstood function in the XmlDocument class in C# (.NET). Programmers probably expects the function to import a set of nodes from one XML document instance to another instance and place the nodes inside the target XML document instance. However, that's not what happened. Reading from MSDN (http://msdn.microsoft.com/en-us/library/system.xml.xmldocument.importnode.aspx):
Importing a node creates an XmlNode object owned by the importing document, with Name and NodeType identical to the source node. The new object also has the attributes related to namespaces (Prefix, LocalName, and NamespaceURI).
After reading the statement at MSDN above, what you should be aware is the ImportNode() method doesn't place the imported set of node in the target XML document. The method merely import the set of node from the context of the source XML document to the target XML document. What I mean by context here have to do with XML namespace. You cannot just place a "rogue" set of nodes without namespace in the target XML document, you have to give a context to the set of nodes, i.e. valid XML namespace, etc. In most cases this is probably what you want to do:
                
foreach (XmlNode currentNode in facts.DocumentElement.ChildNodes)
{
    node = doc.ImportNode(facts.DocumentElement.ChildNodes.Item(i), true);
    doc.DocumentElement.AppendChild(node);
    i++;
}

The code above copies every single child element of the root element of the facts XmlDocument object (source) to the doc XmlDocument (destination) root element.

So, next time you deal with the ImportNode() method, remember that what it does is related to the XML document instance context.

Saturday, July 7, 2012

Caching XSD Schemas in Your .NET Application

If your .NET application deals with linked XSD files, you might find it very inefficient to re-load the linked XSDs every time the application starts. One of the real world example of this is the XBRL taxonomy schemas, which is linked to numerous XSDs defining different parts of the XBRL standard. Now, how do you cache the XSDs schemas locally? For the caching to work, you need to use .NET 4.0 because the caching-related classes is only available in .NET 4.0. Now, let me show you how I make the caching works in Gepsio (one of the open source XBRL implementation):

  1. Goto the project (JeffFerguson.Gepsio project) and change the "Target Framework" to ".NET Framework 4".
  2. Add the following code to XbrlSchema.cs file: 
  3. using System.Net.Cache; // This line added for caching support
    
    //...
    
    public class XbrlSchema
        {
    //...
    private XmlUrlResolver thisXmlUrlResolver;
    
    //...
     internal XbrlSchema(XbrlFragment ContainingXbrlFragment, 
                         string SchemaFilename, string BaseDirectory)
         {
             thisContainingXbrlFragment = ContainingXbrlFragment;
             this.Path = GetFullSchemaPath(SchemaFilename, BaseDirectory);
    
             try
      {
        var schemaReader = XmlTextReader.Create(this.Path);
        thisXmlSchema = XmlSchema.Read(schemaReader, null);
        thisXmlSchemaSet = new XmlSchemaSet();
    
    ///---- START caching with XmlUrlResolver
               thisXmlUrlResolver = new XmlUrlResolver();
               thisXmlUrlResolver.CachePolicy = new  
                         RequestCachePolicy(RequestCacheLevel.CacheIfAvailable);
               thisXmlSchemaSet.XmlResolver = thisXmlUrlResolver;
    ///----- END caching with XmlUrlResolver 
    
               thisXmlSchemaSet.Add(thisXmlSchema); 
        thisXmlSchemaSet.Compile();
    
    //...
    
Well, actually I found the call to the XmlSchemaSet object (thisXmlSchemaSet) to be particularly the biggest bottleneck with Visual Studio profiler when dealing with lots of XBRL instance files because XmlSchemaSet always download the XSD dependencies from xbrl.org.

A side note: the CachePolicy member of the XmlUrlResolver class is not available in .NET Framework version < 4.0 . That's the reason why you have to switch the project to .NET Framework 4.0.

Perhaps, you're not aware of this: the call to XmlSchemaSet.Add() will traverse every linked XSD schemas   until all of them are resolved. Now, if the location of the schemas are remote, that incurs very high penalty to the speed of your application and that wastes unnecessary bandwidth. In this case, schema caching comes to the rescue.

Friday, June 22, 2012

Amelia Earhart Last Trip Footnote

I never knew before that Amelia Earhart did a stop in Bandung after a flight from Bangkok in her last flight, the attempt to encircle the globe: http://acepilots.com/earhart2.html. It's rather surprising and not-so-surprising at the same time.

I have known for several years that the Netherland/Dutch East Indies Government (now Indonesia) did try to establish aviation "center" in Bandung despite its rather bad location (sorrounded by mountains, Bandung was prehistoric lake long ago).


Wednesday, June 20, 2012

Automotive Night Vision (civilian version of FLIR?)

When you read this: http://en.wikipedia.org/wiki/Automotive_night_vision. Every single one of the implementation reads like a Forward Looking Infra-Red (FLIR: http://en.wikipedia.org/wiki/Forward_looking_infrared) to me. To be more precise, read this line from GM implementation of the automotive night vision: "This system was developed with Raytheon and worked by using an infrared sensing camera mounted behind the vehicle's grille".

Now, why would Raytheon is in there? if it's not for FLIR tech, then I'd be surprised. The question is: what kind of FLIR sensor is being used? I think it must've been the  long-wave infrared (LWIR) cameras because it doesn't need Cryogenic cooling which is almost impossible in the target vehicle, given the required size and energy requirement.

Another question is will this technology be adopted en-masse? Time will tell. But, to be sure this is a dual use tech.