13.11. XPath-Einsatz

Allgemeine Erläuterungen zu XPath in PDFUnit

Die Nutzung von XPath zur Bestimmung von Teilen eines PDF-Dokumentes öffnet ein weites Feld von Testmöglichkeiten, das mit einer API alleine nicht abgedeckt werden kann.

Verschiedene Kapitel enthalten schon eine Beschreibung der XPath-Testfunktionen, sofern die Testbereiche XPath-Tests besitzen. Dieses Kapitel hier dient als Übersicht mit Verweisen zu den Spezialkapitel.

// Validating a single PDF using XPath:
.hasXFAData().matchingXPath(..)         3.36: „XFA Daten“ 
.hasXMPData().matchingXPath(..)         3.37: „XMP-Daten“ 
.hasZugferdData().matchingXPath(..)     3.39: „ZUGFeRD“ 

// Comparing two documents using XPath: 
.haveXFAData().matchingXPath(..)        4.15: „XFA-Daten vergleichen“ 
.haveXMPData().matchingXPath(..)        4.16: „XMP-Daten vergleichen“ 

Daten als XML extrahieren

Für alle Teile eines PDF-Dokumentes, für die es XPath-Tests gibt, und für nicht sichtbare Eigenschaften eines Dokumentes werden Extraktionsprogramme zur Verfügung gestellt:

// Utilities to extract XML from PDF:

com.pdfunit.tools.ExtractBookmarks
com.pdfunit.tools.ExtractFieldInfo
com.pdfunit.tools.ExtractFontInfo
com.pdfunit.tools.ExtractNamedDestinations
com.pdfunit.tools.ExtractSignatureInfo
com.pdfunit.tools.ExtractXFAData
com.pdfunit.tools.ExtractXMPData
com.pdfunit.tools.ExtractZugferdData

Die Hilfsprogramme werden im Kapitel 9.1: „Allgemeine Hinweise für alle Hilfsprogramme“ genauer beschrieben.

Namensräume mit Präfix

Namensräume, für die ein Präfix definiert ist, werden von PDFUnit automatisch erkannt.

Default-Namensraum

Der Default-Namensraum kann nicht automatisch ermittelt werden, weil es in einem XML-Dokument prinzipiell mehrere Default-Namensräume geben darf. Aus diesem Grund muss der Default-Namensraum im Test angegeben werden. Er kann mit einem beliebigen Präfix verwendet werden:

/**
 * The default namespace has to be declared, 
 * but any alias can be used for it.
 */
@Test
public void hasXFAData_UsingDefaultNamespace() throws Exception {
  String filename = "documentUnderTest.pdf";
  DefaultNamespace defaultNS = new DefaultNamespace("http://www.xfa.org/schema/xci/2.6/");
  XMLNode aliasFoo = new XMLNode("foo:log/foo:to", "memory", defaultNS);

  AssertThat.document(filename)
            .hasXFAData()
            .withNode(aliasFoo)
  ;
}

Es sieht komisch aus, das willkürliche Prefix zu foo zu verwenden, aber der Java-Standard verlangt ein beliebiges Präfix. Es darf aus Java-Sicht nicht weggelassen werden. In der Praxis wählen Sie bitte ein sprechenderes Prefix.

Das nächste Beispiel zeigt die Deklaration des Default-Namensraumes für eine XPathExpression:

@Test
public void hasXMPData_MatchingXPath_WithDefaultNamespace() throws Exception {
  String filename = "documentUnderTest.pdf";

  String xpathAsString = "//default:format = 'application/pdf'";
  String stringDefaultNS = "http://purl.org/dc/elements/1.1/";
  DefaultNamespace defaultNS = new DefaultNamespace(stringDefaultNS);        
  XPathExpression expression = new XPathExpression(xpathAsString, defaultNS); 

  AssertThat.document(filename)
            .hasXMPData()
            .matchingXPath(expression)
  ;
}

XPath-Kompatibilität

Für XPath-Ausdrücke stehen im Prinzip alle Syntaxelemente und Funktionen von XPath zur Verfügung. Allerdings ist die Menge der tatsächlich verfügbaren Funktionen von der Version des verwendeten XML-Parsers und XSLT-Prozessors abhängig. PDFUnit verwendet den vom JDK mitgelieferten XML-Parser bzw. XSLT-Prozessor (Standard JAXP). Insofern bestimmt die jeweils verwendete Java-Engine die Kompatibilität zum XPath-Standard.

Das Kapitel 13.12: „JAXP-Konfiguration“ erläutert die allgemeine JAXP-Konfiguration eines JRE/JDK, um z.B. Xerces als externen XML-Parser zu nutzen.