Open-XML-SDK icon indicating copy to clipboard operation
Open-XML-SDK copied to clipboard

DocumentFormat.OpenXml.Packaging.CoreFilePropertiesPart has no functional properties

Open daniel-white opened this issue 7 years ago • 21 comments

Description

DocumentFormat.OpenXml.Packaging.CoreFilePropertiesPart has no functional properties. I'd like to access at least the tags, description and title elements. There seems to be a well defined schema for it.

Information

  • .NET Target: .NET Core
  • DocumentFormat.OpenXml Version: (ie 2.8.2)

** Concept API surface **

public class CoreProperties
{
    public string Category { get; set; } 
    public ContentStatusType ContentStatus { get; set; }
    public DateTimeOffset CreatedAt {get; set;}
    public string CreatedBy {get; set; }
    public string Summary {get; set; }
    public IReadOnlyCollection<Keyword> Keywords {get; }
    public string Language {get; set; }
    public string LastModifiedBy {get; set; }
    public DateTimeOffset? LastModifiedAt {get; set; }
    public DateTimeOffset? LastPrintedAt {get; set; }
    public int? Revision {get; set; }
    public int? Version {get; set; }
    public string Subject {get; set; }
    public string Title {get; set; }
}

public class Keyword
{
    public string Language { get; set; }
    public string Value { get; set; }
}

public enum ContentStatusType 
{
    Draft,
    Reviewed,
    Final
}

daniel-white avatar Jan 25 '18 13:01 daniel-white

@daniel-white I haven't played with it much but System.IO.Packaging has the core properties, perhaps as a workaround you can use these: https://msdn.microsoft.com/en-us/library/system.io.packaging.packageproperties(v=vs.110).aspx?

tomjebo avatar Jan 25 '18 20:01 tomjebo

and for implementer reference, the properties are defined in 29500-2 11.1 Core Properties Part. @daniel-white confirm that's what your looking for in the generated package.g.cs CoreFilePropertiesPart class? so this likely will be another enhancement to the schema gen code on the back end. (thanks for the suggestion!)

tomjebo avatar Jan 25 '18 20:01 tomjebo

Yea. That has it. The productivity tool knows its a CoreFilePropertiesPart, but with a blob of xml.

daniel-white avatar Jan 25 '18 20:01 daniel-white

For the community, 29500-2 can be downloaded here: http://standards.iso.org/ittf/PubliclyAvailableStandards/c061796_ISO_IEC_29500-2_2012.zip

tomjebo avatar Jan 25 '18 20:01 tomjebo

Is this request to just expose a well defined set of properties? If so, we can do that without the schema generator updated. @daniel-white can you provide a C# example of what the properties should look like?

twsouthwick avatar Jan 29 '18 15:01 twsouthwick

I'm guessing it should match the PackageProperties. perhaps

CoreFilePropertiesPart part = ....
part.PackageProperties...

daniel-white avatar Jan 29 '18 15:01 daniel-white

In order to decide whether to add it or not, we'll need the actual API surface area that should be considered for the discussion. Would you want to do that?

twsouthwick avatar Jan 29 '18 15:01 twsouthwick

I'm thinking something like this based on the standard:

class CoreProperties
{
    public string Category { get; set; } // category
    public ContentStatusType ContentStatus { get; set; } // contentStatus
    public DateTime CreatedAt {get; set;} //created
    public string CreatedBy {get; set; } // creator
    public string Summary {get; set; } // description
    public List<Keyword> Keywords {get; set; } // keywords
    public string Language {get; set; } // language
    public string LastModifiedBy {get; set; } // lastModifiedBy
    public DateTime? LastModifiedAt {get; set; } // modified
    public DateTime? LastPrintedAt {get; set; } // lastPrinted
    public int? Revision {get; set; } // revision
    public int? Version {get; set; } // version
    public string Subject {get; set; } // subject
    public string Title {get; set; } // title
}

daniel-white avatar Jan 29 '18 16:01 daniel-white

This is package level, right? So it would be something like:

public abstract class OpenXmlPackage
{
   public CoreFilePropertiesPart CoreFilePropertiesPart { get; }
}

Are there any other places this would need to be accessible from?

twsouthwick avatar Jan 29 '18 16:01 twsouthwick

Yea I think it is, thats where i found it. Not sure if its used elsewhere. I dont know the standard well enough.

daniel-white avatar Jan 29 '18 16:01 daniel-white

A couple items on your API:

  • I think for the Keywords, we should return a ICollection<Keyword> instead of List<Keyword>
  • The Keywords property should probably only have a get method and no set
  • I know DateTime is used often throughout the SDK, but current practice recommends using DateTimeOffset.
  • What should Keyword look like?
  • What should ContentStatusType look like?

twsouthwick avatar Jan 29 '18 16:01 twsouthwick

Yeah, I'm not well versed enough in the standard to know off the top of my head, either. @tomjebo @tarunchopra can you guys comment here?

twsouthwick avatar Jan 29 '18 16:01 twsouthwick

  • I'm fine with that. I didn't know if it needed to be ordered or not.
  • No worries.
  • Below:
class Keywords {
    string Language { get; set; }
    string Value { get; set; }
}
  • Below (using the SDK enum facilities):
enum ContentStatusType 
{
    Draft,
    Reviewed,
    Final
}

daniel-white avatar Jan 29 '18 16:01 daniel-white

Cool. Can you update the initial issue to have the APIs discussed here? We'll want someone who knows the spec a bit more than I do to sign off as well (@tomjebo @tarunchopra @ThomasBarnekow) but this looks good to me.

twsouthwick avatar Jan 29 '18 16:01 twsouthwick

@daniel-white I cleaned up the API proposal a bit.

We may want to consider making Keyword a struct.

twsouthwick avatar Jan 30 '18 21:01 twsouthwick

Has this feature been added? It's been a year since the last discussion comment.

Still34 avatar Jan 05 '19 12:01 Still34

Stale issue message

github-actions[bot] avatar May 15 '20 00:05 github-actions[bot]

Bump for refreshing the issue; has this been implemented anywhere yet?

Still34 avatar May 22 '20 02:05 Still34

Bruh. Why it was closed if it was almost done?

megapro17 avatar Apr 04 '24 16:04 megapro17

Not sure why it was closed - reopening so if anyone wants to continue with the design/implementation

twsouthwick avatar Apr 04 '24 16:04 twsouthwick

@megapro17 - Please feel free to submit a PR with your proposed changes.

AlfredHellstern avatar Aug 20 '24 18:08 AlfredHellstern

This issue qualifies as "ancient". :\

@megapro17 I see that we do actually have access to the core.xml properties but they are just not accessible via the generated CoreFilePropertiesPart class.

We have the PackageProperties property on the OpenXmlPackage derived classes like WordprocessingDocument, SpreadsheetDocument and PresentationDocument. Here's a quick sample showing access to these:

using DocumentFormat.OpenXml.Packaging;

using (WordprocessingDocument doc = WordprocessingDocument.Open(args[0], true))
{

    if (doc is not null)
    {
        doc.PackageProperties.Title = "Tom's fancy prop test";
        doc.PackageProperties.Creator = "Tom";
        doc.PackageProperties.Created = DateTime.Today;
    }
}

Based on this, if we want to expose these properties through the generated CoreFilePropertiesPart class, the simplest way would be to provide a CoreFileProperties property in that class that returns an instance of the PackageProperties object from the parent package. I've tested this with an extension to CoreFilePropertiesPart like this:

// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace DocumentFormat.OpenXml.Packaging
{
    /// <summary>
    /// Defines the CoreFilePropertiesPart
    /// </summary>
    public partial class CoreFilePropertiesPart : OpenXmlPart,
        IFixedContentTypePart
    {
        /// <summary>
        /// Gets the package (core.xml) properties.
        /// </summary>
        public IPackageProperties CoreFileProperties => OpenXmlPackage.PackageProperties;
    }
}

With this we can do:

        doc.CoreFilePropertiesPart.CoreFileProperties.Title = "Tom's New Fancy prop test";

This works.

Since this is so old, I will close this issue. I've created a PR for the extension fix in #1895. We can discuss further there if needed.

tomjebo avatar Mar 12 '25 18:03 tomjebo