2017-08-30 8 views
0

Je dois lire et écrire dans les métadonnées XMP d'un fichier PDF/A. J'utilise itextsharp 7 et j'ai essayé plusieurs façons d'atteindre mon objectif, sans beaucoup de succès. Les domaines comme control:Anzahl_Zeichen_Titel sont ma cible. Le code suivant devrait faire le travail, mais je ne peux pas comprendre exactement comment.Lecture et écriture de métadonnées XML dans un document PDF/A

PdfADocument pdfADocument = new PdfADocument(new PdfReader(Vorlage), new PdfWriter(Ausgabe), new StampingProperties()); 
XMPMeta xmpMeta = XMPMetaFactory.ParseFromBuffer(pdfADocument.GetXmpMetadata()); 
XMPProperty test1 = xmpMeta.GetProperty("ftx:ControlData", "control:Anzahl_Zeichen_Vorname"); 
XMPProperty test2 = xmpMeta.GetProperty("http://www.aiim.org/pdfa/ns/schema#", "ControlData"); 

Lorsque j'utilise la version test1 il me montre un XMPException "espace de noms de schéma URI non enregistré". La seconde semble fonctionner mais la variable test2 est nulle.

<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> 
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c015 84.159810, 2016/09/10-02:41:30  "> 
    <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/" 
      xmlns:dc="http://purl.org/dc/elements/1.1/" 
      xmlns:pdf="http://ns.adobe.com/pdf/1.3/" 
      xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" 
      xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" 
      xmlns:pdfaExtension="http://www.aiim.org/pdfa/ns/extension/" 
      xmlns:pdfaSchema="http://www.aiim.org/pdfa/ns/schema#" 
      xmlns:pdfaProperty="http://www.aiim.org/pdfa/ns/property#" 
      xmlns:pdfaType="http://www.aiim.org/pdfa/ns/type#" 
      xmlns:pdfaField="http://www.aiim.org/pdfa/ns/field#" 
      xmlns:ftx="http://ns.ftx.com/forms/1.0/" 
      xmlns:control="http://ns.ftx.com/forms/1.0/controldata/"> 
     <xmp:CreatorTool>QuarkXPress(R) 8.12</xmp:CreatorTool> 
     <xmp:CreateDate>2017-03-14T08:56:49+01:00</xmp:CreateDate> 
     <xmp:ModifyDate>2017-04-11T14:35:21+02:00</xmp:ModifyDate> 
     <xmp:MetadataDate>2017-04-11T14:35:21+02:00</xmp:MetadataDate> 
     <dc:format>application/pdf</dc:format> 
     <!-- snip --> 
     <ftx:ControlData rdf:parseType="Resource"> 
      <control:Anzahl_Zeichen_Titel>0</control:Anzahl_Zeichen_Titel> 
      <control:Anzahl_Zeichen_Vorname>0</control:Anzahl_Zeichen_Vorname> 
      <control:Anzahl_Zeichen_Namenszusatz>0</control:Anzahl_Zeichen_Namenszusatz> 
      <control:Anzahl_Zeichen_Hausnummer>0</control:Anzahl_Zeichen_Hausnummer> 
      <control:Anzahl_Zeichen_Postleitzahl>0</control:Anzahl_Zeichen_Postleitzahl> 
      <control:Anzahl_Zeichen_Wohnsitzlaendercode>0</control:Anzahl_Zeichen_Wohnsitzlaendercode> 
      <control:Auftragsnummer_Einsender>0</control:Auftragsnummer_Einsender> 
      <control:Formularnummer>10</control:Formularnummer> 
      <control:Formularversion>07.2017</control:Formularversion> 
     </ftx:ControlData> 
     </rdf:Description> 
    </rdf:RDF> 
</x:xmpmeta> 
<?xpacket end="w"?> 

Comment dois-je utiliser les méthodes pour créer et lire des données valides?

Répondre

0

Avec l'aide de la réponse de mkl, j'ai trouvé comment lire et écrire les données nécessaires.

private const string NsControlData = "http://ns.ftx.com/forms/1.0/"; 
private const string NsControl = "http://ns.ftx.com/forms/1.0/controldata/"; 

// Opens the template file as PDF/A document. 
PdfADocument pdfADocument = new PdfADocument(new iText.Kernel.Pdf.PdfReader("input.pdf"), new PdfWriter("output.pdf"), new StampingProperties()); 

// Reading the metadata from input file. 
byte[] xmpMetadata = pdfADocument.GetXmpMetadata(); 

// Parse the metadata 
XMPMeta parser = XMPMetaParser.Parse(xmpMetadata, new ParseOptions()); 

// Read a value 
XMPProperty anzahlZeichenTitel = parser.GetStructField(NsControlData, "ControlData", NsControl, "Anzahl_Zeichen_Titel"); 
// Write a value 
parser.SetStructField(NsControlData, "ControlData", NsControl, "Anzahl_Zeichen_Titel", "333"); 

// writing new file with new metadata. 
pdfADocument.SetXmpMetadata(parser); 
pdfADocument.GetWriter().Flush(); 
pdfADocument.Close(); 
1

XMPMeta.getProperty est documentée comme:

/** 
* The property value getter-methods all take a property specification: the first two parameters 
* are always the top level namespace URI (the &quot;schema&quot; namespace) and the basic name 
* of the property being referenced. See the introductory discussion of path expression usage 
* for more information. 
* <p> 
* All of the functions return an object inherited from <code>PropertyBase</code> or 
* <code>null</code> if the property does not exists. The result object contains the value of 
* the property and option flags describing the property. Arrays and the non-leaf levels of 
* nodes do not have values. 
* <p> 
* See {@link PropertyOptions} for detailed information about the options. 
* <p> 
* This is the simplest property getter, mainly for top level simple properties or after using 
* the path composition functions in XMPPathFactory. 
* 
* @param schemaNS The namespace URI for the property. May be <code>null</code> or the empty 
*  string if the first component of the propName path contains a namespace prefix. The 
*  URI must be for a registered namespace. 
* @param propName The name of the property. May be a general path expression, must not be 
*  <code>null</code> or the empty string. Using a namespace prefix on the first 
*  component is optional. If present without a schemaNS value then the prefix specifies 
*  the namespace. The prefix must be for a registered namespace. If both a schemaNS URI 
*  and propName prefix are present, they must be corresponding parts of a registered 
*  namespace. 
* @return Returns a <code>XMPProperty</code> containing the value and the options or 
*   <code>null</code> if the property does not exist. 
* @throws XMPException Wraps all errors and exceptions that may occur. 
*/ 
XMPProperty getProperty(String schemaNS, String propName) throws XMPException; 

En particulier, le premier paramètre doit être un URI d'espace de nom , si

XMPProperty test1 = xmpMeta.GetProperty("ftx:ControlData", "control:Anzahl_Zeichen_Vorname"); 

est évidemment faux.

Votre seconde alternative

XMPProperty test2 = xmpMeta.GetProperty("http://www.aiim.org/pdfa/ns/schema#", "ControlData"); 

a bien un espace de noms URI comme premier paramètre. Malheureusement, ce n'est pas l'URI de l'espace de noms pour la propriété en question qui est http://ns.ftx.com/forms/1.0/.

Ainsi, vous devriez essayer

XMPProperty test2 = xmpMeta.GetProperty("http://ns.ftx.com/forms/1.0/", "ControlData"); 

ou (parce schemaNS comme documenté peut être null ou la chaîne vide si le premier composant du chemin de propName contient un préfixe d'espace de noms)

XMPProperty test2 = xmpMeta.GetProperty(null, "ftx:ControlData"); 
+0

Ceci n'est que partiellement utilisable. Il existe des différences entre itext et itextsharp. GetProperty ne fonctionne pas sans un espace de noms propre. Il ne peut pas être nul ou une chaîne vide. Mais la première version aide à aller plus loin. Quand je regarde dans la structure de données, il retourne mes valeurs nécessaires. – Booser

+0

Mais il n'a aucune méthode pour y accéder. Je suis en train de jouer avec les différentes méthodes pour obtenir les valeurs finales. 'contrôle: Formularnummer' et ainsi de suite. Ils ne peuvent pas être lus comme montré. 'xmpMeta.DoesPropertyExist (" http://ns.ftx.com/forms/1.0/controldata/ "," control: Formularnummer ");' dit NON. – Booser