Getting the list of un-registred namespace for assets | Community
Skip to main content
Level 2
May 29, 2025
Question

Getting the list of un-registred namespace for assets

  • May 29, 2025
  • 3 replies
  • 570 views

Background: We are trying to cleanup the DAM and there are som many assets that got migrated from elsewhere, from what i know Assets were literally dumped in the AEM DAM.

Task: We are trying to cleanup the DAM by moving very old and unused assets to a archive folder.

Issue: In order to do so we have used ACS commons Bulk Move Operation from the Renovator and also created a custom Asset Move operation using Granite Asset API. 
[1]. ACS commons - Shows the successful Dry run and breaks in between due to some NameSpace not existing issue. and dose not updates what assets got moved - which leads again a manual process to do this activity.
[2]. Cannot Use OOTB move operations as we have more than 20k assets from different location.
3. Created a Custom Move Operation which uses the features and overcomes the drawback of [1] and [2]. Provides the report of the assets that did not move and dose not break the job in between if any asset failed to move.

Question: My question here is I can optimize this custom solution more by identifying the assets that have non existing namespace in AEM and probably delete them from the source location without moving them around or create a list of those assets. 

The Most Important question here is how to analyse any asset if they have non-existing namespace also I don't have the list of non-existing namespaces so that we should not rely on the predefined list.

Please provide your valuable insights on this. 

This post is no longer active and is closed to new replies. Need help? Start a new post to ask your question.

3 replies

giuseppebaglio
Level 10
May 29, 2025

hi @kr_saurabh1707,

I cannot think of anything quick and out of the box. Here's what I would do.

 

First get the list of namespaces:

Next, I would create a package to download all asset metadata (excluding renditions) using the following filter settings:

Root path: /content/dam/your/root Rules: Exclude=.*/renditions/.*

 

After extracting the package contents, run the following bash command to find all used namespaces:

grep -R -e "[a-zA-Z0-9]*:[a-zA-Z0-9]*=" | cut -d: -f2 | sed -e 's/^[[:space:]]*//' | grep -v "<" | grep -v Binary | sort -u

Result:

cq crs dam dc exif exifEX Iptc4xmpCore jcr photoshop psAux sling stEvt stRef tiff xmp xmpMM xmpRights

 

To identify missing namespaces, compare the list of used namespaces with all available namespaces in your instance, found under “/jcr:system/rep:namespaces”. You can then execute a command to find assets with the missing namespaces.

grep -R xmp:

The command will return both the path and the property's key-value pair.

./jcr_root/content/dam/we-retail/en/activities/hiking/hiking_2.jpg/.content.xml: xmp:CreateDate="{Date}2015-07-22T11:47:36.000-07:00" ./jcr_root/content/dam/we-retail/en/activities/hiking/hiking_2.jpg/.content.xml: xmp:CreatorTool="Adobe Photoshop CC 2015 (Macintosh)" ./jcr_root/content/dam/we-retail/en/activities/hiking/hiking_2.jpg/.content.xml: xmp:MetadataDate="{Date}2016-01-17T11:33:08.000-05:00" ./jcr_root/content/dam/we-retail/en/activities/hiking/hiking_2.jpg/.content.xml: xmp:ModifyDate="{Date}2016-01-17T11:33:08.000+01:00" ./jcr_root/content/dam/we-retail/en/activities/hiking/hiking_4.jpg/.content.xml: xmp:CreateDate="{Date}2015-07-22T11:48:48.000-07:00" ./jcr_root/content/dam/we-retail/en/activities/hiking/hiking_4.jpg/.content.xml: xmp:CreatorTool="Adobe Photoshop CC 2015 (Macintosh)" ./jcr_root/content/dam/we-retail/en/activities/hiking/hiking_4.jpg/.content.xml: xmp:MetadataDate="{Date}2016-01-14T10:58:11.000-08:00" ./jcr_root/content/dam/we-retail/en/activities/hiking/hiking_4.jpg/.content.xml: xmp:ModifyDate="{Date}2016-01-14T10:58:11.000+01:00"

This can be easily converted into a CSV file to be used as input. Now, you can create a custom workflow step that processes each CSV entry by deleting the property with the missing namespace from the asset.

Excerpt code to delete a property (AI generated):

/** * Deletes a specified property from a JCR node. * * @param resourceResolver The ResourceResolver instance to access the JCR. * @param nodePath The JCR path to the node (e.g., "/content/dam/myasset/jcr:content/metadata"). * @param propertyName The name of the property to delete (e.g., "my:customProperty"). * @return true if the property was found and deleted, false otherwise. */ public boolean deleteProperty(ResourceResolver resourceResolver, String nodePath, String propertyName) { if (resourceResolver == null || nodePath == null || propertyName == null || nodePath.isEmpty() || propertyName.isEmpty()) { LOG.warn("Invalid input: resourceResolver, nodePath, or propertyName cannot be null or empty."); return false; } Session session = null; try { // 1. Adapt ResourceResolver to JCR Session session = resourceResolver.adaptTo(Session.class); if (session == null) { LOG.error("Could not adapt ResourceResolver to JCR Session."); return false; } // 2. Check if the node exists if (!session.nodeExists(nodePath)) { LOG.warn("Node does not exist at path: {}", nodePath); return false; } // 3. Get the Node Node node = session.getNode(nodePath); // 4. Check if the property exists on the node if (!node.hasProperty(propertyName)) { LOG.info("Property '{}' does not exist on node '{}'. No action taken.", propertyName, nodePath); return false; } // 5. Delete the property node.getProperty(propertyName).remove(); LOG.debug("Attempting to remove property '{}' from node '{}'.", propertyName, nodePath); // 6. Save the changes to the repository session.save(); LOG.info("Successfully deleted property '{}' from node '{}'.", propertyName, nodePath); return true; } catch (RepositoryException e) { LOG.error("RepositoryException occurred while deleting property '{}' from node '{}': {}", propertyName, nodePath, e.getMessage(), e); // In case of an error, it's good practice to revert pending changes if (session != null && session.hasPendingChanges()) { try { session.refresh(false); // Discard all pending changes LOG.info("Discarded pending changes due to error."); } catch (RepositoryException refreshEx) { LOG.error("Error refreshing session after deletion failure: {}", refreshEx.getMessage(), refreshEx); } } return false; } finally { // 7. Close the ResourceResolver (and indirectly the Session) // If the ResourceResolver was obtained for this specific operation, close it. // If it was passed from an external service that manages its lifecycle, do not close it here. // For most Sling services, you'd want to close the resolver when you're done with it. if (resourceResolver != null && resourceResolver.isLive()) { // The ResourceResolver.close() will also close the associated JCR Session resourceResolver.close(); LOG.debug("ResourceResolver closed."); } } }

 

AmitVishwakarma
Community Advisor
Community Advisor
May 29, 2025

Hi @kr_saurabh1707 ,

Try below steps:

Step 1: Get the List of Registered Namespaces in AEM

Use CRXDE or JCR Explorer:

Path:

/jcr:system/rep:namespaces

Each namespace appears like:

<ns:dc xmlns:ns="http://www.jcp.org/jcr/1.0">dc</ns:dc> <ns:dam xmlns:ns="http://www.adobe.com/dam/1.0">dam</ns:dam>

Export this to a valid-namespaces.txt file.

 

comm -23 used-namespaces.txt valid-namespaces.txt > missing-namespaces.txt

This gives you the unregistered / unknown namespaces used in DAM assets.

 

Step 5: Identify Assets with Unregistered Namespaces

You can now build a report via Java:

Java Logic (in a workflow or service)

public List<String> findAssetsWithInvalidNamespaces(ResourceResolver resolver, Set<String> invalidNamespaces) { List<String> invalidAssets = new ArrayList<>(); Iterator<Resource> assets = resolver.findResources("SELECT * FROM [dam:Asset]", Query.JCR_SQL2); while (assets.hasNext()) { Resource asset = assets.next(); Resource metadata = asset.getChild("jcr:content/metadata"); if (metadata != null) { ValueMap vm = metadata.getValueMap(); for (String key : vm.keySet()) { if (key.contains(":")) { String ns = key.split(":")[0]; if (invalidNamespaces.contains(ns)) { invalidAssets.add(asset.getPath()); break; // Skip after first invalid namespace found } } } } } return invalidAssets; }

Step 6: Clean or Report

Now that you have the list of invalid assets:

Generate CSV report for manual review

Or automate deletion of invalid properties:

if (node.hasProperty("invalid:property")) { node.getProperty("invalid:property").remove(); }

Or skip assets altogether during your custom bulk move logic.

Regards,
Amit

 

kautuk_sahni
Community Manager
Community Manager
July 1, 2025

@kr_saurabh1707 

Just checking in — were you able to resolve your issue?
We’d love to hear how things worked out. If the suggestions above helped, marking a response as correct can guide others with similar questions. And if you found another solution, feel free to share it — your insights could really benefit the community. Thanks again for being part of the conversation!

Kautuk Sahni