Author: tilman
Date: Wed Nov 26 19:55:52 2025
New Revision: 1930018

Log:
PDFBOX-2378: avoid rdf namespace declarations getting lost in serialization

Modified:
   pdfbox/branches/2.0/xmpbox/src/main/java/org/apache/xmpbox/XMPMetadata.java
   
pdfbox/branches/2.0/xmpbox/src/main/java/org/apache/xmpbox/xml/DomXmpParser.java
   
pdfbox/branches/2.0/xmpbox/src/main/java/org/apache/xmpbox/xml/XmpSerializer.java
   
pdfbox/branches/2.0/xmpbox/src/test/java/org/apache/xmpbox/parser/DeserializationTest.java

Modified: 
pdfbox/branches/2.0/xmpbox/src/main/java/org/apache/xmpbox/XMPMetadata.java
==============================================================================
--- pdfbox/branches/2.0/xmpbox/src/main/java/org/apache/xmpbox/XMPMetadata.java 
Wed Nov 26 19:10:43 2025        (r1930017)
+++ pdfbox/branches/2.0/xmpbox/src/main/java/org/apache/xmpbox/XMPMetadata.java 
Wed Nov 26 19:55:52 2025        (r1930018)
@@ -21,6 +21,7 @@
 package org.apache.xmpbox;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -61,7 +62,9 @@ public class XMPMetadata
 
     private String xpacketEndData = XmpConstants.DEFAULT_XPACKET_END;
 
-    private List<XMPSchema> schemas;
+    private final List<XMPSchema> schemas;
+
+    private Map<String, String> rdfAttributeMap = Collections.emptyMap();
 
     private TypeMapping typeMapping;
 
@@ -596,4 +599,23 @@ public class XMPMetadata
         schemas.clear();
     }
 
+    /**
+     * Get the rdf attribute map (namespace declarations). This is used in 
serialization.
+     *
+     * @return the rdf attribute map.
+     */
+    public Map<String, String> getRdfAttributeMap()
+    {
+        return Collections.unmodifiableMap(rdfAttributeMap);
+    }
+
+    /**
+     * Set the rdf attribute map (namespace declarations). This is used in 
serialization.
+     *
+     * @param rdfAttributeMap an rdf attribute map.
+     */
+    public void setRdfAttributeMap(Map<String, String> rdfAttributeMap)
+    {
+        this.rdfAttributeMap = rdfAttributeMap;
+    }
 }

Modified: 
pdfbox/branches/2.0/xmpbox/src/main/java/org/apache/xmpbox/xml/DomXmpParser.java
==============================================================================
--- 
pdfbox/branches/2.0/xmpbox/src/main/java/org/apache/xmpbox/xml/DomXmpParser.java
    Wed Nov 26 19:10:43 2025        (r1930017)
+++ 
pdfbox/branches/2.0/xmpbox/src/main/java/org/apache/xmpbox/xml/DomXmpParser.java
    Wed Nov 26 19:55:52 2025        (r1930018)
@@ -198,6 +198,22 @@ public class DomXmpParser
                 dataDescriptions.add(description);
             }
         }
+
+        // PDFBOX-2378: keep rdf namespace declarations for later serialization
+        NamedNodeMap attributes = rdfRdf.getAttributes();
+        if (attributes != null)
+        {
+            Map<String, String> rdfAttributeMap = new HashMap<String, 
String>();
+            for (int i = 0; i < attributes.getLength(); ++i)
+            {
+                Node item = attributes.item(i);
+                if 
(XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(item.getNamespaceURI()))
+                {
+                    rdfAttributeMap.put(item.getNodeName(), 
item.getNodeValue());
+                }
+            }
+            xmp.setRdfAttributeMap(rdfAttributeMap);
+        }
         // find schema description
         PdfaExtensionHelper.populateSchemaMapping(xmp);
         // parse data description

Modified: 
pdfbox/branches/2.0/xmpbox/src/main/java/org/apache/xmpbox/xml/XmpSerializer.java
==============================================================================
--- 
pdfbox/branches/2.0/xmpbox/src/main/java/org/apache/xmpbox/xml/XmpSerializer.java
   Wed Nov 26 19:10:43 2025        (r1930017)
+++ 
pdfbox/branches/2.0/xmpbox/src/main/java/org/apache/xmpbox/xml/XmpSerializer.java
   Wed Nov 26 19:55:52 2025        (r1930018)
@@ -99,6 +99,12 @@ public class XmpSerializer
         {
             rdf.appendChild(serializeSchema(doc, schema));
         }
+        // PDFBOX-2378: avoid rdf namespace declarations getting lost in 
serialization
+        Map<String, String> rdfAttributeMap = metadata.getRdfAttributeMap();
+        for (Map.Entry<String, String> entry : rdfAttributeMap.entrySet())
+        {
+            rdf.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, 
entry.getKey(), entry.getValue());
+        }
         // save
         save(doc, os, "UTF-8");
     }

Modified: 
pdfbox/branches/2.0/xmpbox/src/test/java/org/apache/xmpbox/parser/DeserializationTest.java
==============================================================================
--- 
pdfbox/branches/2.0/xmpbox/src/test/java/org/apache/xmpbox/parser/DeserializationTest.java
  Wed Nov 26 19:10:43 2025        (r1930017)
+++ 
pdfbox/branches/2.0/xmpbox/src/test/java/org/apache/xmpbox/parser/DeserializationTest.java
  Wed Nov 26 19:55:52 2025        (r1930018)
@@ -358,8 +358,9 @@ public class DeserializationTest
     }
 
     @Test
-    public void testWihtAttributesAsProperties() throws XmpParsingException, 
TransformerException, NoSuchAlgorithmException, UnsupportedEncodingException, 
IOException
+    public void testWithAttributesAsProperties() throws XmpParsingException, 
TransformerException, NoSuchAlgorithmException, IOException
     {
+        // also serves as a test for the changes in PDFBOX-2378
         InputStream is = 
DomXmpParser.class.getResourceAsStream("/validxmp/attr_as_props.xml");
         XMPMetadata metadata = xdb.parse(is);
 
@@ -372,7 +373,7 @@ public class DeserializationTest
         XMPBasicSchema basic = metadata.getXMPBasicSchema();
         Assert.assertNotNull(basic.getCreateDate());
         
-        checkTransform(metadata, 
"91466370449938102905842936306160100538543510664071400903097987792216034311743");
+        checkTransform(metadata, 
"18065297971979344549773207273794555094175502580946345976611821901439849242965");
         is.close();
     }
 

Reply via email to