XMP steht für „Extensible Metadata Platform“ und ist ein von Adobe initiierter offener Standard, Metadaten in beliebige Dateitypen einzubetten. Nicht nur PDF-Dokumente, auch Bilder können Informationen über den Ort, das Format und andere „Daten über Daten“ einbinden.
Die Metadaten in PDF sind für die Weiterverarbeitung durch andere Programme wichtig und sollten daher richtig sein. Zum Testen bietet PDFUnit die gleichen Tags an, wie für XFA-Daten:
<!-- Tags to test XMP data: --> <hasXMPData /> <hasNoXMPData /> <!-- Inner tags of hasXMPData: --> <hasXMPData> <matchingXPath /> (optional) <matchingXML /> (optional) <withNode /> (optional) </hasXMPData>
Die nächsten Beispiele zeigen die Prüfung der An- bzw. Abwesenheit von XMP-Daten:
<testcase name="hasXMPData"> <assertThat testDocument="xmp/metadata-added.pdf"> <hasXMPData /> </assertThat> </testcase>
<testcase name="hasNoXMPData"> <assertThat testDocument="xmp/bookmarkWithURLAction_noXMP.pdf"> <hasNoXMPData /> </assertThat> </testcase>
Mit dem Hilfsprogramm ExtractXMPData
können die XMP-Daten eines PDF-Dokumentes
in eine XML-Datei exportiert werden. XMP-Daten eines PDF-Dokumentes können dann gegen diese
XML-Datei verglichen werden:
<testcase name="hasXMPData_MatchingXML"> <assertThat testDocument="xmp/metadata-added.pdf"> <hasXMPData> <matchingXML file="xmp/metadata-added.xml" /> </hasXMPData> </assertThat> </testcase>
XMP-Daten eines PDF-Dokumentes können gezielt auf einzelne XML-Knoten und ihren Wert überprüft werden. Das nächste Beispiel basiert auf dem folgenden XML-Ausschnitt:
<x:xmpmeta xmlns:x="adobe:ns:meta/"> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> ... <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/"> <xmp:CreateDate>2011-02-08T15:04:19+01:00</xmp:CreateDate> <xmp:ModifyDate>2011-02-08T15:04:19+01:00</xmp:ModifyDate> <xmp:CreatorTool>My program using iText</xmp:CreatorTool> </rdf:Description> ... </rdf:RDF> </x:xmpmeta>
Für den Test auf einen Knoten aus den XMP-Daten steht das Tag
<withNode />
zur Verfügung.
Nachfolgend wird die Existenz zweier Knotens geprüft:
<testcase name="hasXMPData_WithNode_ValidateExistence"> <assertThat testDocument="xmp/metadata-added.pdf"> <hasXMPData> <withNode name="xmp:CreateDate" /> <withNode name="xmp:ModifyDate" /> </hasXMPData> </assertThat> </testcase>
Soll auch der Wert eines Knotens überprüft werden, muss der erwartete
Wert im Attribut value=".."
angegeben werden:
<!-- When the node name occurs multiple times in the document, only the first node will be returned. --> <testcase name="hasXMPData_WithNodeAndValue"> <assertThat testDocument="xmp/metadata-added.pdf"> <hasXMPData> <withNode name="xmp:CreateDate" value="2011-02-08T15:04:19+01:00" /> <withNode name="xmp:ModifyDate" value="2011-02-08T15:04:19+01:00" /> </hasXMPData> </assertThat> </testcase>
Existiert ein gesuchter Knoten mehrfach innerhalb der XMP-Daten, wird der erste Treffer verwendet.
Der XPath-Ausdruck für den Knoten darf die Wurzel (document root) nicht
enthalten, weil PDFUnit intern //
ergänzt.
Der Knoten darf selbstverständlich auch ein Attribut-Knoten sein.
Mit dem Tag <matchingXPath />
kann das ganze Potential
von XPath genutzt werden:
<testcase name="hasXMPData_MatchingXPath_CreateDateWithValue"> <assertThat testDocument="xmp/metadata-added.pdf"> <hasXMPData> <matchingXPath expr="//xmp:CreateDate[node() = '2011-02-08T15:04:19+01:00']" /> </hasXMPData> </assertThat> </testcase>
<testcase name="hasXMPData_MatchingXPath_MultipleInvocation"> <assertThat testDocument="xmp/metadata-added.pdf"> <hasXMPData> <matchingXPath expr="count(//xmp:CreateDate) = 1" /> <matchingXPath expr="count(//xmp:CreateDate[1][node()='2011-02-08T15:04:19+01:00']) = 1" /> </hasXMPData> </assertThat> </testcase>
Der Funktionsumfang der Verarbeitung der XPath-Ausdrücke hängt vom verwendeten XML-Parser bzw. der XPath-Engine ab. PDFUnit verwendet die des JDK/JRE und unterliegt damit den Unterschieden der unterschiedlichen JVM-Hersteller.
Wie schon für XFA-Tests beschrieben, werden XML-Namensräume automatisch ermittelt. Default-Namensräume müssen vorgegeben werden, weil sie im XML-Dokument mehrfach auftreten können und deshalb nicht aus dem Dokument abgeleitet werden können.
Hier die Verwendung des Default-Namensraumes für das Tag <matchingXPath />
:
<testcase name="hasXMPData_MatchingXPath_WithDefaultNamespace"> <assertThat testDocument="xmp/metadata-added.pdf"> <hasXMPData> <matchingXPath expr="//foo:format = 'application/pdf'" defaultNamespace="http://purl.org/dc/elements/1.1/" /> </hasXMPData> </assertThat> </testcase>
Und noch ein Beispiel für den Default-Namensraum im Tag
<withNode />
mit einem Erwartungswert:
<testcase name="hasXMPData_WithDefaultNamespace_XMLNode"> <assertThat testDocument="xmp/metadata-added.pdf"> <hasXMPData> <withNode name="foo:ModifyDate" value="2011-02-08T15:04:19+01:00" defaultNamespace="http://ns.adobe.com/xap/1.0/" /> </hasXMPData> </assertThat> </testcase>