RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Using OPC to Store Your Own Data : Page 2

Office Open XML uses OPC to store documents. Here's how to use packages for your own purposes.


It's All About Relationships

At this point, you've added a part to the package, but there's no good way to navigate from the package to the part. For that, you need to create a relationship. Each Package contains a list of relationships. Each PackagePart also has a list of relationships. Each relationship can point to either an internal PackagePart or an external URI.

Creating a relationship between the package and the picturePart is straightforward:

   Const Package2Picture As String = _
   _package.CreateRelationship(picturePart.Uri, _
      TargetMode.Internal, _   
The last parameter in the call to CreateRelationship is important. You'll need this value later to enumerate the relationships from the package to the various picture parts.

Adding Picture Metadata

Now that we've added the image itself to the package, you need to add the metadata for that picture. An easy way to do this is to create another part that will hold an XML file:

   Dim uri As New Uri("pictures/Bee.jpg.xml", _
   Dim pictureInfoPart As PackagePart = _package.CreatePart(uri, _
      System.Net.Mime.MediaTypeNames.Text.Xml, _
You can use the PictureInfo class to give the picture a name and a description, and then use an XmlSerializer to create the XML from the PictureInfo:

   Dim pictureInfo As New PictureInfo()
   pictureInfo.Name = "Bee"
   pictureInfo.Description = "A stunning picture of a bee."
   Using stream As IO.Stream = _
      Dim serializer As New XmlSerializer(GetType(PictureInfo))
      serializer.Serialize(stream, pictureInfo)
   End Using

Creating a Relationship Between PackageParts

With the picture and the metadata stored in PackageParts, you now need to create a relationship between the picture and its information. That's straightforward, and similar to code you've already seen:

   Const Picture2PictureInfo As String = _
   picturePart.CreateRelationship(pictureInfoPart.Uri, _
       TargetMode.Internal, _
Now the two parts are related.

Getting the Data Out

Now that you've inserted all this meaningful information, you also need a way to get it out. The manual way (and a good way to check what you've done so far) is to rename the album file to Album1.zip and inspect the contents (see Figure 3):

Figure 3. Package Contents: The figure shows the contents of the album package.
In Figure 3, you can see the two added PackageParts. Also, note the presence of the _rels folder, which stores the relationships for all the parts in this folder.

To read the contents of this package from code, you first open the package (if it's not already open):

   Dim package As Package = package.Open( _
      "c:\Album1.palb", IO.FileMode.Open)
Then, enumerate the relationships between the package and the pictures (here's where you need that Package2Picture argument I noted earlier).

   Dim pictureRelationships = _
Now, you can enumerate the pictureRelationships list to get the images. For each relationship, retrieve the picturePart, and then get the data via a Stream:

   For Each pictureRelationship In pictureRelationships
      Dim picturePart As PackagePart = _
      Dim image As Image
      Using stream As IO.Stream = _
         image = image.FromStream(stream)
      End Using
You also enumerate the relationships to get the metadata for each picture, deserializing the data into a PictureInfo instance:

   Dim relationships = _
   'In production code, you would want to make sure that there
   ' is a relationship before doing this.
   Dim relationship As PackageRelationship = relationships(0)
   Dim pictureInfoPart As PackagePart = _
   Dim pictureInfo As PictureInfo
   Using stream As IO.Stream = _
      Dim serializer As New XmlSerializer( _
      pictureInfo = DirectCast( _
         serializer.Deserialize(stream), _
   End Using

Deleting an Image

Deleting a PackagePart is simple. The following code deletes the pictureInfo XML file as well as the picture itself:

DeletePart automatically deletes the relationships that were created from that part. However, it does not delete relationships to that part. To do that, you need the relationship ID. One way to get this ID is to keep track of it when creating the relationship. The other is to store it when enumerating the relationships.


Close Icon
Thanks for your registration, follow us on our social networks to keep up-to-date