PDF가 자기 자신에 대해 아는 것: 메타데이터와 XMP 패킷
Spec: ISO 16684-1:2019ISO 16684-1:2019Spec: ISO 32000-2ISO 32000-2
한눈에 보기
섹션 제목: “한눈에 보기”현대적인 PDF를 열면 그것이 자기 자신에 대해 두 번 이야기할 수도 있습니다. 문서 정보 딕셔너리라고 불리는 작고 오래된 키/값 목록이 있고, 같은 것을 훨씬 풍부하고 구조화된 형식으로 말하는 XML 블록 — XMP 패킷 — 이 있을 수 있습니다. 이 페이지는 그 두 개의 병행 시스템과, 둘 다 살아남은 이유, 그리고 보관 및 검색 파이프라인이 둘의 합치를 고집하는 이유에 관한 것입니다.
제목에 대한 짧은 답. PDF는 자신의 제목, 저자, 주제, 키워드, 자신을 만든 도구, 그리고 언제인지를 압니다. 그것은 그 지식을 한 번에 두 곳에 저장하며, 흥미로운 공학은 그 둘을 정직하게 유지하는 데 있습니다.
왜 중요한가
섹션 제목: “왜 중요한가”메타데이터는 사람이 좀처럼 보지 않고 기계가 거의 항상 읽는 문서의 부분입니다. 운영체제의 파일 미리 보기, 디지털 자산 관리자, 도서관 목록, 검색 색인, 법적 증거 개시 도구 — 그중 다수가 문서 텍스트보다 먼저, 또는 그와 나란히 메타데이터를 읽고, 그것이 말하는 바를 신뢰합니다.
그래서 두 시스템이 불일치할 때 — 정보 딕셔너리는 한 저자를 말하고 XMP 패킷은 다른 저자를 말할 때 — 하류의 무언가가 하나를 고르고, 어느 쪽인지는 여러분이 선택할 수 없습니다. 검색 색인이 잘못된 제목을 표면화할 수도 있습니다. 보관 검증기가 파일을 즉시 거부할 수도 있습니다. 그 어긋남은 파이프라인이 그것에 걸려 넘어질 때까지 보이지 않으며, 그것은 발견하기에 최악의 시점입니다.
- PDF는 두 개의 병행 시스템으로 메타데이터를 담을 수 있습니다. 즉, 레거시 문서 정보 딕셔너리와 RDF/XML로 된 현대적인 XMP 패킷입니다.
- XMP 패킷은 xpacket 처리 명령 —
begin헤더와end트레일러 — 으로 감싸지므로, 도구가 파일 전체를 다시 파싱하지 않고도 그것을 찾고, 심지어 제자리에서 다시 쓸 수 있습니다. - 속성은 네임스페이스 안에 있습니다. 제목과 작성자를 위한
dc(Dublin Core), 생성 및 수정 날짜를 위한xmp, 생산자를 위한pdf, 문서 정체성과 이력을 위한xmpMM입니다. - PDF/A는 XMP 메타데이터를 요구하며, XMP에 상응하는 항목이 있는 DocInfo 엔트리는 그것과 일치해야 합니다 — 불일치는 검증 실패입니다.
- NextPDF는 그 둘을 하나의 작업으로 다룹니다. 즉, 둘 다 쓰고, XMP를 다시 읽고, 패킷의 크기를 보호하여, 잘못된 형식의 파일을 내보내는 대신 닫힌 상태로 실패합니다.
NextPDF가 접근하는 방식
섹션 제목: “NextPDF가 접근하는 방식”정직한 틀짓기는 이것이 형식화 문제로 위장한 동기화 문제라는 것입니다. 문서 정보
딕셔너리 (Spec: ISO 32000-2, §14.3.3ISO 32000-2 §14.3.3) 는 트레일러에서 /Info
엔트리로 참조되며, 문자열의 평평한 목록입니다. 즉, 제목, 저자, 주제, 키워드, 작성자,
생산자, 그리고 날짜 두어 개입니다. 그것은 단순하고, XML보다 앞서며, 너무도 많은 도구가
여전히 그것을 먼저 읽기 때문에 거의 모든 파일에 여전히 실려 다닙니다.
XMP 패킷 (Spec: ISO 16684-1:2019, §7ISO 16684-1:2019 §7) 은 현대적인 절반입니다. 그것은 XML 문서 — 정확히는 RDF/XML — 로, 파일을 스키마로 묶인 명명된 속성의 집합으로 모델링하며, 각 스키마는 네임스페이스에 결속됩니다 (Spec: ISO 16684-1:2019, §6ISO 16684-1:2019 §6). 그 구조가 바로 평평한 딕셔너리가 할 수 없는 것입니다. 값은 정렬된 목록, 언어 태그가 붙은 대안(“영어 제목, 프랑스어 제목”), 또는 구조화된 레코드일 수 있습니다. PDF에서 그 XML은 문서 카탈로그에 부착된 메타데이터 스트림 안에 있으며 (Spec: ISO 32000-2, §14.3.2ISO 32000-2 §14.3.2), 이는 현재의 리더가 살펴보는 표준적인 위치입니다.
세 가지 세부 사항이 해부할 가치가 있습니다. 도구가 패킷을 틀리게 다루는 곳이 바로 거기이기 때문입니다.
래퍼. XMP 패킷은 처리 명령으로 괄호 쳐지므로, 패킷이 곧바로 검색 가능한 바이트로
저장되는 형식에서는 프로그램이 전체 파싱 없이 메타데이터를 찾아낼 수 있습니다. PDF에서는
특히 카탈로그 메타데이터 스트림이 표준적인 위치 지정기입니다.
begin 헤더는 텍스트 인코딩을 선언하는 바이트 순서 표시를 담습니다. end 트레일러는
패킷이 읽기 전용인지 아니면 제자리에서 편집될 수 있는지를 진술하는 플래그를 담습니다.
쓰기 가능할 때, 직렬화기는 편집기가 뒤따르는 모든 바이트를 이동시키지 않고도 콘텐츠를
약간 늘릴 수 있도록 XML 뒤에 공백 패딩의 연속을 남깁니다. 그 패딩은 장식이 아닙니다 —
그것이 바로 제자리 메타데이터 편집을 가능하게 하는 것입니다.
네임스페이스. 속성은 자신의 네임스페이스에 대해서만 의미가 있으며, 몇 가지는
거의 보편적입니다. Dublin Core(dc)는 제목과 작성자를 담습니다. XMP 기본
스키마(xmp)는 생성 및 수정 날짜와 작성 도구를 담습니다. PDF 스키마(pdf)는 생산자
문자열과 키워드를 담습니다. 미디어 관리 스키마(xmpMM)는 문서의 정체성과 그 파생
이력 — “이 파일은 저 파일에서 왔다”라고 말하는 자취 — 을 담습니다. 이 네임스페이스
URI와 속성 이름 — 보통 관례적인 접두사로 표시됩니다 — 에 대해 합의하는 것이 바로 코어
스키마의 요점입니다 (Spec: ISO 16684-1:2019, Annex BISO 16684-1:2019 Annex B). Dublin
Core 제목 속성을 둘 다 말하는 두 도구는 사전 약속 없이도 상호 운용됩니다.
일관성 규칙. 두 시스템 모두 같은 속성을 명명할 수 있으므로, 둘은 불일치할 수 있습니다. 보관용 프로파일은 그것을 허용하기를 거부합니다. PDF/A 파일은 XMP 메타데이터 스트림을 담아야 하며, XMP에 상응하는 항목이 있는 모든 문서 정보 엔트리는 그것과 일치해야 합니다. 불일치는 검증 실패입니다. 실용적인 교훈은 직접적입니다. 즉, 보관 파이프라인에서 그 둘은 독립적인 필드가 아니라 두 번 쓰인 하나의 사실이며, 보조를 맞춰 유지되어야 합니다.
NextPDF는 세 가지 모두를 하나의 관심사로 다룹니다. 메타데이터 흐름은 경쟁하는 두 개가 아니라 하나의 경로입니다.
- Collect the values once제목, 저자, 주제, 키워드, 작성자, 생산자, 그리고 날짜가 문서에 단 한 번 설정되므로, 진실의 원천이 둘이 아니라 하나다.
- Write the Info dictionaryDocInfo 라이터가 오래된 도구들이 먼저 읽는 레거시 Title, Author, Subject, Keywords, Creator, Producer 및 날짜 엔트리를 내보낸다.
- Build the XMP packetXMP 빌더가 같은 값을 dc, xmp, pdf, xmpMM 아래의 RDF/XML로 직렬화하여, 쓰기 가능한 패딩과 함께 xpacket 헤더와 트레일러로 감싼다.
- Guard the packet size직렬화가 수용되기 전에, 엔진은 패킷을 크기 한도와 대조하여 검사하고, 잘못된 형식이거나 과대한 스트림을 내보내는 대신 유형이 있는 예외로 닫힌 상태로 실패한다.
- Read XMP back to verifyXMP 리더가 패킷을 파싱하여 엔진이 주어진 메타데이터를 썼음을 파이프라인이 확인할 수 있게 한다 — 보관 검증기가 그 위에 쌓는 종류의 검사다.
실용적인 예제
섹션 제목: “실용적인 예제”아래의 형태는 메타데이터를 한 번 설정하고 엔진이 그것을 두 시스템으로 펼치도록 한 다음, 파이프라인이 검사할 수 있도록 XMP 제목을 다시 읽습니다. 크기 보호는 “아마 괜찮을 것”을 “그렇지 않으면 입증 가능하게 거부됨”으로 바꾸는 행입니다.
<?php
declare(strict_types=1);
use NextPDF\Core\Document;use NextPDF\Metadata\Exception\XmpPacketTooLargeException;
$document = Document::createStandalone();
// Set the values ONCE. The engine writes them to both the Info dictionary// and the XMP packet, so the two systems cannot drift apart at the source.$document->setTitle('Annual Report 2026');$document->setAuthor('Records Office');$document->setSubject('Statutory annual filing');$document->setKeywords('annual report, statutory, 2026');
try { // Building the document serializes the XMP packet. The engine guards the // packet size and fails closed: a packet that exceeds the bound is a // typed exception, never a silently truncated or malformed stream. $bytes = $document->getPdfData();} catch (XmpPacketTooLargeException $e) { // Decide deliberately: trim the metadata, not the guarantees. error_log('XMP packet exceeded the size bound: ' . $e->getMessage()); throw $e;}
// Read the packet back. This confirms the XMP the engine serialized carries the// value you set — the kind of integrity check an archival pipeline runs before// it trusts the file. (Both systems are written from one source, so they agree// by construction; reading the XMP back proves it serialized as intended.)$xmp = $document->readXmpMetadata($bytes);$xmpTitle = $xmp->get('dc', 'title'); // 'Annual Report 2026'
if ($xmpTitle !== $document->getTitle()) { throw new \RuntimeException('XMP title does not match the value that was set.');}여기에는 두 시스템이 조용히 갈라지는 경로가 없습니다. 값은 한 번 들어오고, 두 라이터가 같은 소스를 소비하며, 리더는 파이프라인이 결과를 검사하게 해 줍니다.
흔한 오해
섹션 제목: “흔한 오해”흔한 믿음은 정보 딕셔너리가 구식이므로 무시해도 된다는 것입니다. 무시할 수 없습니다 — 아직은 아닙니다. 일부 운영체제 파일 미리 보기와 오래된 보관 도구를 포함하여 설치된 많은 소프트웨어가 여전히 정보 딕셔너리를 먼저, 또는 오직 그것만 읽습니다. 그것을 버린다고 파일이 현대화되지는 않습니다. 그것은 XMP를 채택하지 않은 모든 것에게 파일이 제목 없는 것처럼 보이게 만듭니다.
거울에 비친 듯한 반대의 실수는 그 둘을 따로 채워 넣는 독립적인 필드로 다루는 것입니다. 그것이 바로 둘이 어긋나는 방식입니다. 그것들은 하나의 사실의 두 직렬화입니다. 하나의 소스에서 쓰십시오. 그러지 않으면 하류의 무언가가 여러분이 의도하지 않은 버전을 고를 것임을 받아들이십시오.
한계와 경계
섹션 제목: “한계와 경계”- NextPDF는 두 시스템을 모두 쓰고 XMP를 다시 읽습니다. 그 범위는 XMP 메타데이터 빌더, DocInfo 라이터, 그리고 XMP 리더입니다. 범용 RDF/XML 쿼리 엔진이 되기로 약속하지 않습니다.
- XMP 패킷은 크기가 보호되며 닫힌 상태로 실패합니다. 엔진의 한도를 초과하는 패킷은 유형이 있는 예외를 일으킵니다. 엔진은 과대한 요청을 “맞추기” 위해 잘리거나, 한도를 넘어 패딩되거나, 그 외 잘못된 형식의 패킷을 내보내지 않습니다.
- 일관성은 하나의 소스에서 쓰기 시점에 강제됩니다. 그것은 여러분이 산출하지 않은 파일에 대한 마법 같은 화해가 아닙니다. 두 시스템이 이미 불일치하는 문서를 가져온다면, 그것을 해결하는 것은 암묵적인 재작성이 아니라 여러분의 결정입니다.
- PDF/A의 메타데이터 요구 사항은 보관용 프로파일의 일부입니다. 이 페이지는 규칙을 설명합니다. 적합성 판정은, 보관 작업에서 늘 그러하듯이, 검증기의 몫입니다. 그 경계는 보관 페이지를 참조하십시오.
메타데이터 빌더, DocInfo 라이터, 그리고 XMP 리더는 코어 역량입니다. 정직한 단서는 아래의 크기 보호와 함께 있습니다.
| Edition | Availability |
|---|---|
| Core | XMP 메타데이터 빌더, 문서 정보 딕셔너리 라이터, 그리고 XMP 리더가, 과대한 패킷에 대해 닫힌 상태로 실패하는 크기 보호와 함께 Core에 포함됩니다 — XMP 메타데이터 스트림을 필수로 만들고 DocInfo가 그것과 일치하도록 요구하는 PDF/A 적합성 출력 및 검증을 포함합니다. |
| Pro | 같은 Core 라이터와 리더 위에 배치 및 템플릿 기반 메타데이터 워크플로를 추가합니다. |
| Enterprise | 문서 자산 전반에 걸친 더 폭넓은 적합성 정책 및 보고 표면을 추가합니다. |
관련 문서
섹션 제목: “관련 문서”- 보관과 PDF/A — XMP 패킷이 선택 사항이기를 멈추고 DocInfo 대 XMP 일관성 규칙이 통과 또는 실패 요구 사항이 되는 곳.
- 감사자에게 건넬 수 있는 적합성 — 왕복하고 자기 자신과 합치하는 메타데이터가 감사 가능한 산출물의 일부인 이유.
- PDF 파일의 해부학 — 트레일러, 카탈로그, 그리고 메타데이터 스트림이 파일 구조 안 어디에 자리 잡는지.
- 스트림과 필터 — 메타데이터 스트림은 스트림입니다. 이것이 PDF 스트림이 인코딩되고 결정론적으로 유지되는 방식입니다.
용어집
섹션 제목: “용어집”- 문서 정보 딕셔너리 — 트레일러에서
/Info엔트리로 참조되는 레거시의 평평한 키/값 메타데이터. 즉, 제목, 저자, 주제, 키워드, 작성자, 생산자, 그리고 날짜입니다. XMP보다 앞서며, 여전히 널리 읽힙니다. - XMP — Extensible Metadata Platform. 명명된 속성을 스키마로 묶어 리소스를 기술하는 XML(RDF/XML) 형식. ISO 16684-1로 표준화됨.
- xpacket — XMP 패킷을 감싸는 처리 명령으로,
begin헤더(인코딩 표시기)와end트레일러(읽기 전용 또는 쓰기 가능 플래그)를 동반하므로, 도구가 전체 파싱 없이 패킷을 찾고 편집할 수 있습니다. - 네임스페이스 / 스키마 — URI에 결속된 속성의 명명된 어휘. 흔한 접두사:
dc(Dublin Core),xmp(XMP 기본),pdf(PDF 고유),xmpMM(미디어 관리 / 문서 정체성). - 메타데이터 스트림 — XMP 패킷을 담는, 문서 카탈로그에 부착된 PDF 객체. 현대적인 리더가 먼저 확인하는 표준적인 위치.
- PDF/A — 보관용 PDF 프로파일 군(ISO 19005). 그것은 XMP 메타데이터 스트림을 요구하고, XMP에 상응하는 항목이 있는 모든 문서 정보 엔트리가 그것과 일치할 것을 요구합니다. 그러지 않으면 검증이 실패합니다.