Freigeben über


The OpenXmlDocument Class

This example takes the plumbing code from Packages and Parts, refactors it a bit, and creates an object graph that will be easy to query using LINQ to XML. There are a few points to note about this code:

This blog is inactive.
New blog: EricWhite.com/blog

Blog TOC· To make reading the code as easy as possible, it was written in the spirit of a dynamic language, such as Python or Ruby. The Relationship class (implemented below) consists of as a set of read/write properties using the new C# 3.0 automatic properties syntax. We don’t really care that much that the properties are in some cases settable, when in fact maybe they should not be. After all, we’re going to write pure functional code that never mutates anything. Our main concern is using a syntax that is as lightweight as possible. We’ll see other examples of this approach later.

· The OpenXmlDocument class implements IDisposable, and in its Dispose method calls the Close method on the Package. IDisposable isn’t really in the spirit of pure, stateless functional programming, but since the Package class implements IDisposable, the correct approach for the OpenXmlDocument class is to also implement IDisposable. Besides, I’m not a purist! And there are times when imperative code is easier to write (and read) than pure FP declarative code.

· The CreateRelationshipList method contains a query that uses a PackageRelationshipCollection as its source, and projects a collection of Relationship objects. By projecting a new collection of our own type of objects, we’ll improve the readability of the code that uses this class, improve the IntelliSense experience, and provide a place to store stuff like our LINQ to XML tree (in an XDocument object).

· To simplify accessing child relationships for a PackagePart, the Relationship class below contains a List<Relationship> property that is initialized when a PackagePart contains a PackageRelationshipCollection.

· This code was compiled with the RTM version of Visual Studio 2008: C# 3.0 and .NET Framework 3.5.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.IO;
using System.IO.Packaging;

namespace Microsoft.Examples.LtxOpenXml
{
class Relationship
{
public string Id { get; set; }
public string RelationshipType { get; set; }
public string ContentType { get; set; }
public System.IO.Packaging.TargetMode TargetMode { get; set; }
public Uri SourceUri { get; set; }
public Uri TargetUri { get; set; }
public PackagePart PackagePart { get; set; }
public XDocument XDocument { get; set; }
public List<Relationship> Relationships { get; set; }
}

class OpenXmlDocument : IDisposable
{
// public
public string Name { get; set; }
public Package Package { get; set; }
public List<Relationship> Relationships { get; set; }

// private
private bool disposed = false;

public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

private void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
Package.Close();
disposed = true;
}
}

private XDocument LoadXDocument(string relationshipType,
PackagePart part)
{
if (XmlContentTypes.Contains(part.ContentType))
return XDocument.Load(XmlReader.Create(part.GetStream()));
else
return null;
}

private List<Relationship> CreateRelationshipList(
PackageRelationshipCollection prc)
{
return (
from pr in prc
where pr.TargetMode == TargetMode.Internal
let uri = PackUriHelper.ResolvePartUri(
new Uri(pr.SourceUri.ToString(), UriKind.Relative),
pr.TargetUri)
let part = pr.Package.GetPart(uri)
let contentType = part.ContentType
let xdoc = LoadXDocument(pr.RelationshipType, part)
let partRelationshipList =
CreateRelationshipList(part.GetRelationships())
select new Relationship
{
Id = pr.Id,
RelationshipType = pr.RelationshipType,
TargetMode = pr.TargetMode,
ContentType = part.ContentType,
SourceUri = pr.SourceUri,
TargetUri = pr.TargetUri,
PackagePart = part,
XDocument = xdoc,
Relationships = partRelationshipList
}
).ToList();
}

public OpenXmlDocument(string name)
{
Name = name;
Package = Package.Open(Name, FileMode.Open, FileAccess.Read);
Relationships = CreateRelationshipList(
Package.GetRelationships());
}

public HashSet<string> XmlContentTypes = new HashSet<string>
{
"application/vnd.openxmlformats-officedocument.custom-properties+xml",
"application/vnd.openxmlformats-officedocument.customXmlProperties+xml",
"application/vnd.openxmlformats-officedocument.drawing+xml",
"application/vnd.openxmlformats-officedocument.drawingml.chart+xml",
"application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml",
"application/vnd.openxmlformats-officedocument.drawingml.diagramColors+xml",
"application/vnd.openxmlformats-officedocument.drawingml.diagramData+xml",
"application/vnd.openxmlformats-officedocument.drawingml.diagramLayout+xml",
"application/vnd.openxmlformats-officedocument.drawingml.diagramStyle+xml",
"application/vnd.openxmlformats-officedocument.extended-properties+xml",
"application/vnd.openxmlformats-officedocument.presentationml.commentAuthors+xml",
"application/vnd.openxmlformats-officedocument.presentationml.comments+xml",
"application/vnd.openxmlformats-officedocument.presentationml.handoutMaster+xml",
"application/vnd.openxmlformats-officedocument.presentationml.notesMaster+xml",
"application/vnd.openxmlformats-officedocument.presentationml.notesSlide+xml",
"application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml",
"application/vnd.openxmlformats-officedocument.presentationml.presentationProperties+xml",
"application/vnd.openxmlformats-officedocument.presentationml.slide+xml",
"application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml",
"application/vnd.openxmlformats-officedocument.presentationml.slideMaster+xml",
"application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml",
"application/vnd.openxmlformats-officedocument.presentationml.slideUpdateInfo+xml",
"application/vnd.openxmlformats-officedocument.presentationml.tableStyles+xml",
"application/vnd.openxmlformats-officedocument.presentationml.tags+xml",
"application/vnd.openxmlformats-officedocument.presentationml.template.main+xml",
"application/vnd.openxmlformats-officedocument.presentationml.viewProps+xml",
"application/vnd.openxmlformats-officedocument.spreadsheetml.calcChain+xml",
"application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml",
"application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml",
"application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml",
"application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml",
"application/vnd.openxmlformats-officedocument.spreadsheetml.externalLink+xml",
"application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCacheDefinition+xml",
"application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCacheRecords+xml",
"application/vnd.openxmlformats-officedocument.spreadsheetml.pivotTable+xml",
"application/vnd.openxmlformats-officedocument.spreadsheetml.queryTable+xml",
"application/vnd.openxmlformats-officedocument.spreadsheetml.revisionHeaders+xml",
"application/vnd.openxmlformats-officedocument.spreadsheetml.revisionLog+xml",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheetMetadata+xml",
"application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml",
"application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml",
"application/vnd.openxmlformats-officedocument.spreadsheetml.tableSingleCells+xml",
"application/vnd.openxmlformats-officedocument.spreadsheetml.userNames+xml",
"application/vnd.openxmlformats-officedocument.spreadsheetml.volatileDependencies+xml",
"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml",
"application/vnd.openxmlformats-officedocument.theme+xml",
"application/vnd.openxmlformats-officedocument.themeOverride+xml",
"application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml",
"application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml",
"application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml",
"application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml",
"application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml",
"application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml",
"application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml",
"application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml",
"application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml",
"application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml",
"application/vnd.openxmlformats-package.core-properties+xml",
"application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml",
"application/xml"
};
}
}

Comments

  • Anonymous
    December 10, 2007
    I have news! I am leaving my current job documenting XML technologies (primarily LINQ to XML), and taking

  • Anonymous
    December 10, 2007
    Given my focus on LINQ to XML over the last couple of years, I have to say that LINQ to XML and Open

  • Anonymous
    March 31, 2008
    Theseresourceisforpreparingtheproject,supervisedbyMONOandGOOGLESUMMERCODE2008,Converti...

  • Anonymous
    March 31, 2008
    These resource is for preparing the project ,supervised by MONO and GOOGLE SUMMER CODE 2008,Converting

  • Anonymous
    May 13, 2008
    Hi, I need ur help. I am unable to dispose XDocument . My requirement is very simple, simple reading and writing to xml file using xdocument. pls provide your inputs to how to proceed.

  • Anonymous
    May 14, 2008
    XDocument doesn't implement IDisposable.  Take a look at the documentation.  This topic shows how to load an XDocument from a file: http://msdn.microsoft.com/en-us/library/bb343181.aspx This topic shows how to save it back to a file: http://msdn.microsoft.com/en-us/library/bb345830.aspx Also, take a look at the LINQ to XML Programming Guide: http://msdn.microsoft.com/en-us/library/bb387087.aspx

  • Anonymous
    May 14, 2008
    Many a Thanks for ur reply. My issue is i have to keep writing xml file through web application, so it wil b written by as many users. If i don;t close or dispose, it says, it is being used by other process.

  • Anonymous
    May 19, 2008
    This example takes the plumbing code from Packages and Parts , refactors it a bit, and creates an object graph that will be easy to query using LINQ to XML. There are a few points to note about this code: &#183; To make reading the code as easy as possible