Наверх

Open Packaging Conventions #4. Метаданные документов

Время чтения: 9 минут
0
Open Packaging Conventions #4. Метаданные документов

Если вы в Word нажмете на закладку Файл, то первая же страница, которая попадется вам на глаза, будет страница Сведения, а большую её часть будет занимать раздел Свойства, а это как раз метаданные документа.

Предыдущая запись Open Packaging Conventions #3. Немного об API.

Если вы откроете Backstage в Word (иначе говоря, нажмете на закладку Файл (File) на Ribbon), то первая же страница, которая попадется вам на глаза, будет страница Сведения (Info), а большую её часть будет занимать раздел Свойства (Properties).

imageРаздел Properties, ничто иное как метаданные документа. Точно такие же разделы можно увидеть в любом продукте из состава Microsoft Office.

Думаю, что у большинства, кто впервые сталкивается со свойствами документа возникает вопрос – для чего они нужны, в чем их полезность? Поэтому, прежде чем переходить к техническим вопросам, позволю себе немного пофилософствовать на тему “метаданных в документе”, всех, кому данный вопрос не интересен, прошу пропустить следующий раздел и сразу же переходить к техническому описанию.

Метаданные документа/файла (небольшое отступление)

Если вы попытаетесь отбросить всю маркетинговую шелуху вокруг управления документами и контентом, в которую которую любят обернуть свои выступления представители вендоров СЭД/ECM, вы можете обнаружить 2 важных факта:

●   практически 100% управления документами/контентом – это контроль соблюдения определенных регламентов работы

●   вся работа ведется на основе структурированных метаданных документов, вне зависимости от того как они были получены (введены руками, автоматически или были извлечены на основе содержимого документа)

Т.е. все системы управления документами работают исключительно на основе метаданных и без них просто теряют смысл. Правда, тут нужно понимать, что практически все они хранят метаданные отдельно от тела документа (это удобнее, надежнее, технологичнее, …), но:

●   с документами работают не только в СЭД, и даже в первую очередь не в СЭД. Созданием, редактированием, показом занимаются, как правило, сторонние приложения.

●   рано или поздно встает вопрос о передаче документов между системами или в среду, где нет совсем никаких систем (физическому лицу, например). И приходится изобретать собственные решения (типа такого) для такой, в общем-то стандартной задачи.

Вообще, мы довольно часто не отдаем себе отчета, что, большинство форматов документов/файлов, которыми пользуемся постоянно содержат большое количество метаданных, которые не требуются непосредственно для работы с этим файлом (например, имя музыканта и название композиции в аудио файле или координаты и дата снимка в графическом)! И даже более того – в стандартном ПО уже есть все, чтобы работать (как минимум читать) эти метаданные.

Вот, например, как выглядят свойства того документа, то и на предыдущем изображении, в Windows Explorer:

image

А вот они же, в специальной области, называемой Document Panel:

image

Ну и, конечно, с метаданными большинства распространенных форматов умеют работать многие ECM-системы (например, SharePoint и Alfresco).

Поэтому предлагаю не откладывая познакомиться с тем, как хранятся метаданные в OPC-документах вообще и Microsoft Office в частности.

Метаданные в OPC-контейнерах

Разрабатывая стандарт OPС, Microsoft предусмотрительно включила в него раздел с описанием метаданных. Т.е. абсолютно все, основанные на OPC документы, уже могут содержать некоторый, небольшой, но стандартизованный, а значит читаемый где угодно стандарт метаданных.

Его описание содержится в главе “Core Properties” в уже знакомом нам документе Part 2 — Open Packaging Conventions. Собственно, тезисно оттуда:

●   метаданные лежат в специальном компоненте, в виде XML

●   тип содержимого компонента application/vnd.openxmlformats-package.core-properties+xml

●   тип связи (компонент должен быть привязан к пакету) http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties

●   наконец сама XML, в которой хранятся метаданные имеет namespace http://schemas.openxmlformats.org/package/2006/metadata/core-properties (в стандарте есть xsd для нее)

Собственно, у нас есть все, чтобы работать с метаданными в OPC:

const string corePropertiesUri =
   "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties";
 
using (var package = Package.Open(@"TestDocuments\TestDocument.docx", FileMode.Open))
{
    var corePropertiesRelationship = package.GetRelationshipsByType(corePropertiesUri)
        .Single();
    var corePropertiesPart = package.GetPart(PackUriHelper.CreatePartUri(
          corePropertiesRelationship.TargetUri));
 
    var reader = new StreamReader(corePropertiesPart.GetStream());
    Console.WriteLine(reader.ReadToEnd());
}

Правда, теперь нам придется еще пройти по XML, выделить нужные свойства, перевести в нужный тип, … А еще нужно не забыть, что компонента со свойствами может и не быть – он не обязательный!

К счастью, в Packaging API есть уже готовые классы для работы с Core Properties, которые можно как читать:

using (var package = Package.Open(@"TestDocuments\TestDocument.docx", FileMode.Open))
{
    var properties = package.PackageProperties;

    Console.WriteLine("Category : {0}", properties.Category);
    Console.WriteLine("ContentStatus : {0}", properties.ContentStatus);
    Console.WriteLine("ContentType : {0}", properties.ContentType);
    Console.WriteLine("Created : {0}", properties.Created);
    Console.WriteLine("Creator : {0}", properties.Creator);
    Console.WriteLine("Description : {0}", properties.Description);
    Console.WriteLine("Identifier : {0}", properties.Identifier);
    Console.WriteLine("Keywords : {0}", properties.Keywords);
    Console.WriteLine("Language : {0}", properties.Language);
    Console.WriteLine("LastModifiedBy : {0}", properties.LastModifiedBy);
    Console.WriteLine("LastPrinted : {0}", properties.LastPrinted);
    Console.WriteLine("Modified : {0}", properties.Modified);
    Console.WriteLine("Revision : {0}", properties.Revision);
    Console.WriteLine("Subject : {0}", properties.Subject);
    Console.WriteLine("Title : {0}", properties.Title);
    Console.WriteLine("Version : {0}", properties.Version);
}

так и менять:

using (var package = Package.Open(@"TestDocuments\TestDocument2.docx",
     FileMode.Open, FileAccess.ReadWrite))
{
    var properties = package.PackageProperties;
 
    properties.Title = "Changed document";
    properties.Modified = DateTime.Now;
    properties.Description = string.Format("Document changed at {0}", properties.Modified);
 
    package.Close();
}

Метаданные в Open XML документах

В дополнение к метаданным, определенным в OPC, первая часть стандарта Open XML добавляет свои. Часть из них (содержащихся в компоненте Extended File Properties) предопределена и описана в стандарте, часть (компонент Custom File Properties) определяется пользователем.

Увы, по сравнению с Packaging API, Open XML SDK не демонстрирует особых удобств в работе, поэтому доступ даже к предопределённым метаданным выглядит куда многословнее (к тому же нужно учитывать – какие свойства доступны в каком типе документов). Но в целом работа с ними выглядит похоже:

using (var document = WordprocessingDocument.Open(fileName, false))
{
    var extendedProperties = document.ExtendedFilePropertiesPart.Properties;
 
    Console.WriteLine("Application : {0}", extendedProperties.Application.Text);
    Console.WriteLine("ApplicationVersion : {0}", extendedProperties.ApplicationVersion.Text);
    Console.WriteLine("Characters : {0}", extendedProperties.Characters.Text);
    Console.WriteLine("CharactersWithSpaces : {0}", extendedProperties.CharactersWithSpaces.Text);
    Console.WriteLine("Company : {0}", extendedProperties.Company.Text);
    Console.WriteLine("HyperlinksChanged : {0}", extendedProperties.HyperlinksChanged.Text);
    Console.WriteLine("Lines : {0}", extendedProperties.Lines.Text);
    Console.WriteLine("LinksUpToDate : {0}", extendedProperties.LinksUpToDate.Text);
    Console.WriteLine("Pages : {0}", extendedProperties.Pages.Text);
    Console.WriteLine("Paragraphs : {0}", extendedProperties.Paragraphs.Text);
    Console.WriteLine("ScaleCrop : {0}", extendedProperties.ScaleCrop.Text);
    Console.WriteLine("SharedDocument : {0}", extendedProperties.SharedDocument.Text);
    Console.WriteLine("Template : {0}", extendedProperties.Template.Text);
    Console.WriteLine("TotalTime : {0}", extendedProperties.TotalTime.Text);
    Console.WriteLine("Words : {0}", extendedProperties.Words.Text);
}

Как обычно, все примеры кода можно найти здесь.

Оригинал записи: в блоге Михаила Романова.

Источник: Блог Михаила Романова.

Чтобы прочитать эту статью до конца,
или зарегистрируйтесь

Комментарии 0

Чтобы прокомментировать, или зарегистрируйтесь