Files
skills/docs/media/image/exif/src/xmp/read-xmp.md
2026-05-29 08:20:56 +01:00

3.2 KiB

readXmp

(no submodules)

Purpose

Parses XMP (Extensible Metadata Platform) metadata from a raw XMP XML string extracted from a JPEG APP1 segment. XMP is Adobe's XML-based metadata format built on RDF/XML. This module extracts the most commonly used Dublin Core fields (dc:creator, dc:description, dc:rights, dc:subject, dc:title) and XMP Rights fields using pattern-based extraction rather than a full XML parser, trading completeness for zero dependencies.

Features

  • Extracts dc:creator as a string array (from rdf:Seq)
  • Extracts dc:description as a language-keyed Record (from rdf:Alt)
  • Extracts dc:rights or xmpRights:UsageTerms as a plain string
  • Extracts dc:subject as a string array (from rdf:Bag)
  • Extracts dc:title as a language-keyed Record (from rdf:Alt)
  • Always returns the raw XMP XML string in the raw field
  • Never throws — partial results on malformed or missing fields

Usage: Basic Example

import { readXmp } from "@suaveplan/exif/xmp";

const xml = `<x:xmpmeta><rdf:RDF>
  <rdf:Description>
    <dc:creator><rdf:Seq><rdf:li>Jane Doe</rdf:li></rdf:Seq></dc:creator>
    <dc:rights>© 2024 Jane Doe</dc:rights>
  </rdf:Description>
</rdf:RDF></x:xmpmeta>`;

const xmp = readXmp(xml);
console.log(xmp.creator); // ["Jane Doe"]
console.log(xmp.rights);  // "© 2024 Jane Doe"

Usage: Advanced Example

import { readXmp } from "@suaveplan/exif/xmp";

const xml = `<x:xmpmeta>
  <rdf:RDF>
    <rdf:Description>
      <dc:title>
        <rdf:Alt>
          <rdf:li xml:lang="en">Sunset over mountains</rdf:li>
          <rdf:li xml:lang="fr">Coucher de soleil sur les montagnes</rdf:li>
        </rdf:Alt>
      </dc:title>
      <dc:subject>
        <rdf:Bag>
          <rdf:li>landscape</rdf:li>
          <rdf:li>sunset</rdf:li>
          <rdf:li>mountains</rdf:li>
        </rdf:Bag>
      </dc:subject>
    </rdf:Description>
  </rdf:RDF>
</x:xmpmeta>`;

const xmp = readXmp(xml);
console.log(xmp.title?.["en"]);  // "Sunset over mountains"
console.log(xmp.title?.["fr"]);  // "Coucher de soleil sur les montagnes"
console.log(xmp.subject);        // ["landscape", "sunset", "mountains"]

API Reference

readXmp(xmlString: string): XmpData

Parses XMP metadata from xmlString.

Returns: XmpData with all recognised fields populated. Always includes raw: xmlString. Fields absent from the XMP are undefined in the result.

Does not throw. Returns { raw: xmlString } on empty or unrecognised input.

XmpData

interface XmpData {
  raw: string;
  creator?: string[];
  description?: Record<string, string>;
  rights?: string;
  subject?: string[];
  title?: Record<string, string>;
}

Implementation Notes

The extraction uses three internal helpers: extractTextNode for simple inline values, extractRdfList for rdf:Bag/rdf:Seq item arrays, and extractRdfAlt for rdf:Alt language maps. Pattern matching is tolerant of namespace prefixes (any prefix or no prefix). The rdf:Alt extraction captures optional xml:lang attributes and defaults to "x-default" when absent. This approach handles the most common XMP output from Lightroom, Photoshop, and camera firmware without the complexity and size of a full DOM parser.