Welcome to MSDN Blogs Sign in | Join | Help
What is the Difference Between the System.IO.Packaging and DocumentFormat.OpenXml.Packaging Namespaces?

(October 1, 2008 - Update - Open XML SDK V2 does help in consuming the XML of the parts.  See this post for more information.) 

There are two separate namespaces, each containing a number of classes, which you can use to open and get at the contents of Open XML documents.

  • System.IO.Packaging is part of the .NET Framework 3.0 and 3.5. The classes are in the WindowsBase assembly.
  • DocumentFormat.OpenXml.Packaging is in an external assembly that you can download and install. The classes are in the DocumentFormat.OpenXml assembly.

Note that neither of the above namespaces help in any way with consuming the XML in the parts. You must still use an XML programming API, such as XmlReader, XmlDocument (or best, LINQ to XML), to consume and if necessary, produce the XML.

To use either of the above two namespaces, you need to add a reference to the appropriate assembly.

The OpenXmlPackaging download can be found here:

http://go.microsoft.com/fwlink/?linkid=120908

You can find documentation for DocumentFormat.OpenXml.Packaging here:

http://msdn2.microsoft.com/en-us/library/bb448854.aspx

There is a bit of confusion about which of these to use.

System.IO.Packaging

As detailed in Packages and Parts, packages are zip files that contain a number of parts, primarily XML, but also can contain other types of parts, such as images.

System.IO.Packaging provides classes that allow you to get at the contents of these zip files. However, it isn’t raw zipfile access; it provides means to use the relationships to navigate from part to part. This navigation is untyped. You use strings to identify the content types, and retrieve part types that are not strongly typed.

The following code shows how to retrieve the main document part and the style part of a WordprocessingML document using this namespace:

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

class Program
{
    static void Main(string[] args)
    {
        const string fileName = "Test.docx";

        const string documentRelationshipType =
          "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument";
        const string stylesRelationshipType =
          "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles";

        XDocument xDoc = null;
        XDocument styleDoc = null;

        using (Package wdPackage = Package.Open(fileName, FileMode.Open, FileAccess.Read))
        {
            PackageRelationship docPackageRelationship =
              wdPackage
              .GetRelationshipsByType(documentRelationshipType)
              .FirstOrDefault();
            if (docPackageRelationship != null)
            {
                Uri documentUri =
                    PackUriHelper
                    .ResolvePartUri(
                       new Uri("/", UriKind.Relative),
                             docPackageRelationship.TargetUri);
                PackagePart documentPart =
                    wdPackage.GetPart(documentUri);

                //  Load the document XML in the part into an XDocument instance.
                xDoc = XDocument.Load(XmlReader.Create(documentPart.GetStream()));

                //  Find the styles part. There will only be one.
                PackageRelationship styleRelation =
                  documentPart.GetRelationshipsByType(stylesRelationshipType)
                  .FirstOrDefault();
                if (styleRelation != null)
                {
                    Uri styleUri = PackUriHelper.ResolvePartUri(documentUri, styleRelation.TargetUri);
                    PackagePart stylePart = wdPackage.GetPart(styleUri);

                    //  Load the style XML in the part into an XDocument instance.
                    styleDoc = XDocument.Load(XmlReader.Create(stylePart.GetStream()));
                }
            }
        }
        Console.WriteLine("The main document part has {0} nodes.", xDoc.DescendantNodes().Count());
        Console.WriteLine("The style part has {0} nodes.", styleDoc.DescendantNodes().Count());
    }
}

DocumentFormat.OpenXml.Packaging

In contrast, the classes in this namespace allow you to use strongly typed access to the contents of packages. These classes reduce the amount of code that you have to write. The following shows how to retrieve the main document part and the style part of a WordprocessingML document using this namespace. You can see that the code is significantly smaller and cleaner.

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

class Program
{
    public static XDocument LoadXDocument(OpenXmlPart part)
    {
        XDocument xdoc;
        using (StreamReader streamReader = new StreamReader(part.GetStream()))
            xdoc = XDocument.Load(XmlReader.Create(streamReader));
        return xdoc;
    }

    static void Main(string[] args)
    {
        const string filename = "Test.docx";

        using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(filename, true))
        {
            MainDocumentPart mainPart = wordDoc.MainDocumentPart;
            StyleDefinitionsPart styleDefinitionsPart = mainPart.StyleDefinitionsPart;
            XDocument xDoc = LoadXDocument(mainPart);
            XDocument styleDoc = LoadXDocument(styleDefinitionsPart);
            Console.WriteLine("The main document part has {0} nodes.", xDoc.DescendantNodes().Count());
            Console.WriteLine("The style part has {0} nodes.", styleDoc.DescendantNodes().Count());
        }
    }
}

Posted: Thursday, December 20, 2007 6:33 PM by EricWhite
Filed under:

Comments

Noticias externas said:

There are two separate namespaces, each containing a number of classes, which you can use to open and

# December 20, 2007 1:48 PM

Doug Mahugh said:

Document Science CTO on Office and Open XML. My good friend Warren Wilbee recently interviewed Dr. Nasser

# December 20, 2007 7:59 PM

Noticias externas said:

Document Science CTO on Office and Open XML. My good friend Warren Wilbee recently interviewed Dr. Nasser

# December 20, 2007 8:57 PM

LINQ in Action roller said:

There are two separate namespaces, each containing a number of classes, which you can use to open and

# December 21, 2007 10:57 AM

Ian Webster said:

Thanks for this Eric. I have referenced it in a email discusion of the warrants of starting a new development using only System.IO.Packaging.

# March 26, 2008 10:56 PM

Eric White's Blog said:

[Table of Contents] [Next Topic] Open XML Packages To follow this tutorial, you don't need to delve into

# May 21, 2008 6:17 PM

Dating said:

There are two separate namespaces, each containing a number of classes, which you can use to open and get at the contents of Open XML documents. · System.IO.Packaging is part of the .NET Framework 3.0 and 3.5. The classes are in the WindowsBase assembly

# May 31, 2008 3:33 PM

Weddings said:

There are two separate namespaces, each containing a number of classes, which you can use to open and get at the contents of Open XML documents. · System.IO.Packaging is part of the .NET Framework 3.0 and 3.5. The classes are in the WindowsBase assembly

# June 5, 2008 4:44 AM

Ying said:

The Microsoft.Office.DocumentFormat.OpenXml.Packaging namespace is renamed to DocumentFormat.OpenXml.Packaging for the OpenXML SDK 1.0 download.

# July 4, 2008 10:22 AM

EricWhite said:

Ying, you are correct.  I've been lax in updating old blog posts to use the new SDK.  I've corrected this one, and will take care of other posts that have the same issue.

# July 4, 2008 11:26 AM

Mehedi said:

Is this two can be use with Framework 2.0 and II6?

# July 21, 2009 5:15 PM

EricWhite said:

Hi Mehedi,

.Net Framework 3.0 is the earliest supported version.

http://msdn.microsoft.com/en-us/library/system.io.packaging.aspx

-Eric

# July 21, 2009 6:05 PM
Leave a Comment

(required) 

(required) 

(optional)

(required) 

  
Enter Code Here: Required

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Page view tracker