Author: tilman
Date: Fri Dec 19 11:29:57 2025
New Revision: 1930725

Log:
PDFBOX-5977: improve namespace handling

Modified:
   
pdfbox/branches/1.8/jempbox/src/main/java/org/apache/jempbox/impl/XMLUtil.java
   
pdfbox/branches/1.8/jempbox/src/main/java/org/apache/jempbox/xmp/XMPMetadata.java
   
pdfbox/branches/1.8/jempbox/src/test/java/org/apache/jempbox/xmp/XMPMetadataTest.java

Modified: 
pdfbox/branches/1.8/jempbox/src/main/java/org/apache/jempbox/impl/XMLUtil.java
==============================================================================
--- 
pdfbox/branches/1.8/jempbox/src/main/java/org/apache/jempbox/impl/XMLUtil.java  
    Fri Dec 19 08:34:41 2025        (r1930724)
+++ 
pdfbox/branches/1.8/jempbox/src/main/java/org/apache/jempbox/impl/XMLUtil.java  
    Fri Dec 19 11:29:57 2025        (r1930725)
@@ -90,6 +90,7 @@ public class XMLUtil
             builderFactory.setFeature(
                     
"http://apache.org/xml/features/nonvalidating/load-external-dtd";, false);
             builderFactory.setXIncludeAware(false);
+            builderFactory.setNamespaceAware(true); // PDFBOX-5977
             DocumentBuilder builder = builderFactory.newDocumentBuilder();
             // prevents validation messages polluting the console
             builder.setErrorHandler(null);

Modified: 
pdfbox/branches/1.8/jempbox/src/main/java/org/apache/jempbox/xmp/XMPMetadata.java
==============================================================================
--- 
pdfbox/branches/1.8/jempbox/src/main/java/org/apache/jempbox/xmp/XMPMetadata.java
   Fri Dec 19 08:34:41 2025        (r1930724)
+++ 
pdfbox/branches/1.8/jempbox/src/main/java/org/apache/jempbox/xmp/XMPMetadata.java
   Fri Dec 19 11:29:57 2025        (r1930725)
@@ -617,30 +617,18 @@ public class XMPMetadata
                 String value = attribute.getNodeValue();
                 if (name.startsWith("xmlns:") && nsMappings.containsKey(value))
                 {
-                    Class<?> schemaClass = nsMappings.get(value);
-                    try
-                    {
-                        Constructor<?> ctor = schemaClass
-                                .getDeclaredConstructor(new Class[] { 
Element.class,
-                                        String.class });
-                        retval.add((XMPSchema)ctor.newInstance(new Object[] { 
schema,
-                                name.substring(6) }));
-                        found = true;
-                    }
-                    catch(NoSuchMethodException e)
-                    {
-                        throw new IOException(
-                                "Error: Class "
-                                        + schemaClass.getName()
-                                        + " must have a constructor with the 
signature of "
-                                        + schemaClass.getName()
-                                        + "( org.w3c.dom.Element, 
java.lang.String )");
-                    }
-                    catch(Exception e)
-                    {
-                        e.printStackTrace();
-                        throw new IOException(e.getMessage());
-                    }
+                    String prefix = name.substring(6);
+                    retval.add(createXMPSchema(value, schema, prefix));
+                    found = true;
+                }
+                // PDFBOX-5977
+                else if (attribute.getNamespaceURI() != null && 
+                         nsMappings.containsKey(attribute.getNamespaceURI()) &&
+                         name.contains(":"))
+                {
+                    String prefix = name.substring(0, name.indexOf(':'));
+                    retval.add(createXMPSchema(attribute.getNamespaceURI(), 
schema, prefix));
+                    found = true;
                 }
             }
             if (!found)
@@ -651,6 +639,32 @@ public class XMPMetadata
         return retval;
     }
 
+    private XMPSchema createXMPSchema(String value, Element schemaElement, 
String prefix) throws IOException
+    {
+        Class<?> schemaClass = nsMappings.get(value);
+        try
+        {
+            Constructor<?> ctor = schemaClass
+                    .getDeclaredConstructor(new Class[] { Element.class,
+                        String.class });
+            return (XMPSchema) ctor.newInstance(new Object[] { schemaElement, 
prefix });
+        }
+        catch(NoSuchMethodException e)
+        {
+            throw new IOException(
+                    "Error: Class "
+                            + schemaClass.getName()
+                            + " must have a constructor with the signature of "
+                            + schemaClass.getName()
+                            + "( org.w3c.dom.Element, java.lang.String )");
+        }
+        catch(Exception e)
+        {
+            e.printStackTrace();
+            throw new IOException(e.getMessage());
+        }
+    }
+
     /**
      * Will return all schemas that fit the given namespaceURI. Which is only
      * done by using the namespace mapping (nsMapping) and not by actually

Modified: 
pdfbox/branches/1.8/jempbox/src/test/java/org/apache/jempbox/xmp/XMPMetadataTest.java
==============================================================================
--- 
pdfbox/branches/1.8/jempbox/src/test/java/org/apache/jempbox/xmp/XMPMetadataTest.java
       Fri Dec 19 08:34:41 2025        (r1930724)
+++ 
pdfbox/branches/1.8/jempbox/src/test/java/org/apache/jempbox/xmp/XMPMetadataTest.java
       Fri Dec 19 11:29:57 2025        (r1930725)
@@ -16,12 +16,14 @@
  */
 package org.apache.jempbox.xmp;
 
+import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.StringReader;
 import java.util.Calendar;
 import java.util.GregorianCalendar;
 
 import junit.framework.TestCase;
+import org.apache.jempbox.xmp.pdfa.XMPSchemaPDFAId;
 
 import org.xml.sax.InputSource;
 
@@ -139,4 +141,18 @@ public class XMPMetadataTest extends Tes
         assertEquals("uuid:2c7eb5da-9210-4666-8cef-e02ef6631c5e", 
mediaManagementSchema.getInstanceID());
     }
 
-}
+    public void testPDFBOX5977() throws IOException
+    {
+        String s = "<?xml version=\"1.0\" encoding=\"UTF-8\" 
standalone=\"no\"?>\n" +
+                    "<?xpacket begin=\"\" 
id=\"W5M0MpCehiHzreSzNTczkc9d\"?><rdf:RDF 
xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"; " +
+                    "xmlns:pdf=\"http://ns.adobe.com/pdf/1.3/\"; 
xmlns:pdfaid=\"http://www.aiim.org/pdfa/ns/id/\";>\n" +
+                    " <rdf:Description pdfaid:conformance=\"B\" 
pdfaid:part=\"3\" rdf:about=\"\"/>\n" +
+                    " <rdf:Description pdf:Producer=\"WeasyPrint 64.1\" 
rdf:about=\"\"/>\n" +
+                    "</rdf:RDF><?xpacket end=\"r\"?>";
+        XMPMetadata xmp = XMPMetadata.load(new 
ByteArrayInputStream(s.getBytes()));
+        xmp.addXMLNSMapping(XMPSchemaPDFAId.NAMESPACE, XMPSchemaPDFAId.class);
+        XMPSchemaPDFAId schema = (XMPSchemaPDFAId) 
xmp.getSchemaByClass(XMPSchemaPDFAId.class);
+        assertEquals("B", schema.getConformance());
+        assertEquals((Integer) 3, schema.getPart());
+    }
+}
\ No newline at end of file

Reply via email to