2017-08-30 104 views
0

我需要讀取和寫入PDF/A文件的XMP元數據。在PDF/A文檔中讀取和寫入xml元數據

我使用的是itextsharp 7,並嘗試了幾種方法來實現我的目標,但沒有取得太大的成功。像control:Anzahl_Zeichen_Titel這樣的字段是我的目標。 下面的代碼應該做的工作,但我不明白究竟如何。

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"); 

當我使用test1版本時,它顯示了一個XMPException「未註冊模式名稱空間URI」。 第二個似乎工作,但test2變量爲空。

<?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"?> 

如何使用這些方法來創建和讀取有效數據?

回答

0

在mkl的答案幫助下,我發現如何讀取和寫入所需的數據。

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被記錄爲:

/** 
* 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; 

特別地,第一參數必須是一個命名空間URI,所以

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

顯然是錯誤的。

你的第二替代

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

正確具有命名空間URI作爲第一個參數。不幸的是,它不是的http://ns.ftx.com/forms/1.0/名稱空間URI。

因此,你應該嘗試

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

或(因爲schemaNS如記錄可能null或空字符串,如果PROPNAME路徑的第一部分包含一個命名空間前綴

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

這只是部分可用。 itext和itextsharp之間有區別。如果沒有適當的命名空間,GetProperty不起作用。它不能爲空或空字符串。但第一個版本更進一步。當我查看數據結構時,它會返回我需要的值。 – Booser

+0

但它沒有任何訪問它們的方法。我正在用不同的方法來獲得最終的價值。 'control:Formularnummer'等等。他們不能像所顯示的那樣閱讀。 'xmpMeta.DoesPropertyExist(「http://ns.ftx.com/forms/1.0/controldata/」,「control:Formularnummer」);'說不。 – Booser