As its name implies, OpenXML is XML-centric technology (i.e. which extensively uses XML to describe the meta-model and contents of each and every element of a document).
OpenXML documents themselves (MS Word, Excel, PowerPoint…) are compressed packages that include numerous xml files which describe the document's meta-models and contents.
To explore these items, you can simply rename the document file to .zip and then navigate through this zip archive to view the elements that may be of interest.
After proceeding this way, you of course must not forget to rename the file back to its original extension (.docx, .xlsx… or whatever). When working on an OpenXML project, you obviously have to do this so many times a day, which becomes a somehow daunting task!
Some very good tools exist to explore OpenXML documents' structures… but most of them expose a logical view of the document rather than an xml-centric view. Which is of course very helpful… but does not apply when you just need to see the physical structure and the xml content of meta-models and elements.
Moreover, most of these tools are somehow out dated (2007-2009…) and many simply crash on most of our 'modern era' OSs!
Add some other good reasons to write another explorer:
It is august, it is raining and I don't know what to do this week end (while listening to Maria Joao Pires playing Mozart Sonatas!)
The purpose and tools?
What I need is:
- Open an OpenXML document as a zip archive (without having to rename it to .zip!)
- Explore the content of the archive (folders / files)
- Explore / search the xml tree of xml files that may be found there
Adding a reference to System.IO.Compression and System.IO.Compression.FileSystem, you can (relatively easily) present the archive tree structure like in the following image:
I created a view model layer to map my needs to the zip archive objects of the System.IO.Compression namespace:
iZipEntryVM: a view model for zip archive entry which offers some useful properties related to my purpose.
iZipEntryVmList: a collection of the above object which offers static methods to create the tree of a zip archive file as well as a 'selected item' property and selection change event.
iOfficeVM: (singleton) entry point ('main view model' in a way) that orchestrates the basic commands and selection change events.
XML property bags explorer, again, to the rescue!
I wrote in a previous post about using PropertyBags to explore xml nodes.
The xml explorer objects, methods and controls written during this research are now packaged into an independent library that can be referenced in the current project.
What I have to do is just wire the selection event of an item in the archive tree to the xml explorer objects.
That is, when I click an xml file on the zip archive tree, the selection change event is fired. If the selected item is an xml content, it is opened and its stream is sent to the xml explorer object to display the node tree.
In practice:
- On the TreeView control's selection changed event, the SelectedItem of the view model collection (iZipEntryVmList) is set.
- The collection fires its own Selection changed event.
- iOfficeVM subscribes to that event and send the entry stream to the xml explorer:
_myArchiveList.SelectedItemChanged += _list_SelectedItemChanged
private async void _list_SelectedItemChanged(object sender, iZipEntryVM selectedItem)
{
ZipArchiveEntry entry = selectedItem.ZipEntry;
if(entry == null)
return;
if(selectedItem.IsXmlFile)
await Task.Run(() => OpenXmlFile(selectedItem));
}
async void OpenXmlFile(iZipEntryVM entryVm)
{
ZipArchiveEntry zentry = entryVm.ZipEntry;
var bagVm = XmlExplorer.Instance.PropertyBagVM;
if(bagVm != null)
{
Stream stream;
await Task.Run(() =>
{
stream = zentry.Open();
// this will build the xml nodes' property bag tree
bagVm.SourceStream = stream;
});
}
}
Apart from presenting the xml nodes' tree, XML explorer offers some other useful features:
- Search for content values and/or node names
- View / copy the xml string of a selected node
- Export (save) the current OpenXML item to a file.
And, not less important, I no more have to rename a file to do that…!
Some screenshots
Explorer General View
Sample search results
Binaries and source code
You may download the binaries here
You may also download the source code here.