vrijdag 13 januari 2012

Reconstructing an OpenXml Element from Xml

First of all let me wish everyone out there a happy new year!  Keep on coding and off course keep on reading my blog :-P

So now back to business.  A couple of months ago, while I was writing the WordProcessingSerialization project, I've bumped into a little problem.   The OpenXml SDK 2.0 lets you read the OuterXml of an OpenXmlElement but it doesn’t allow you to construct an OpenXml element from XML.  Yet I think that this is an issue for allot of developers that want to save the raw XML for later reuse.  Last week I seem to have bumped into this problem again so I thought let’s fix this!

It proved rather difficult to construct the OpenXml element from XML.  The main reason why it was that difficult is because there doesn’t seem to be a factory class in the SDK that does the conversion.  Instead when I looked at the implementation of the SDK I was kind of chocked that the development team opted for such a weird implementation (and gigantic flaw in separation of concerns).  It seems that each individual OpenXml is responsible for constructing their children.  Here is a small example of their code:

     internal override OpenXmlElement ElementFactory(byte namespaceId, string name)
      if (23 == (int) namespaceId && "rPr" == name)
        return (OpenXmlElement) new RunProperties();
      if (23 == (int) namespaceId && "br" == name)
        return (OpenXmlElement) new Break();
      if (23 == (int) namespaceId && "t" == name)
        return (OpenXmlElement) new Text();
      if (23 == (int) namespaceId && "delText" == name)
        return (OpenXmlElement) new DeletedText();
      if (23 == (int) namespaceId && "instrText" == name)
        return (OpenXmlElement) new FieldCode();

So after some more peeking it was obvious to me that if I wanted to create some kind of factory class, I was going to have to do it myself.  Without boring you too much with pages of code I’ll give you the link to the Git Repository where you can download the project yourself.

The usage of the code is very easy:

var element1 = new OpenXmlElementReconstructor().Reconstruct(outerXml)

So you just create an instance of the OpenXmlElementReconstructor and call the Reconstruct method which accepts a parameter that contains the Xml value.

At the time of writing the library is 80% completed.  I reassemble the OpenXmlElements by searching for their implementation with reflection but I’m planning on creating a preassembled map of all OpenXmlElements so the execution time will be faster.  Current execution times are 439 milliseconds at the first execution time and from then on 47 milliseconds for subsequent calls.  The first call is pretty heavy but that should be solved when I have finished the preassembled map.


Download link: https://github.com/LucBos/OpenXmlFactory