Expand my Community achievements bar.

Don’t miss the AEM Skill Exchange in SF on Nov 14—hear from industry leaders, learn best practices, and enhance your AEM strategy with practical tips.

Xpath Query in AEM 6.3

Avatar

Level 3

Hello Everyone,

I have below use case:

EXISTING CODE:

private static final String MAIN_QUERY = "/jcr:root/content/data/myproject/products//*[@sling:resourceType='myproject/common/components/template1']";

Iterator<Resource> it = this.resourceResolver.findResources(String.format(MAIN_QUERY), XPATH);

int counter = 10000;

while (it.hasNext()) {

resource = it.next();

if (null != resource) {

parentResource = resource.getParent().getParent();

CustomAdaptor myVar = parentResource.adaptTo(CustomAdaptor.class);

}

counter++;

}

Structure in CRX/DE:

content/data/myproject/products/mainproduct1

/childproduct1.1

/childproduct1.2

/childproduct1.3

/childproduct1.4

content/data/myproject/products/mainproduct2

/childproduct2.1

/childproduct2.2

/childproduct2.3

/childproduct2.4

Here, mainproduct1 has sling:resourceType='myproject/common/components/template1 and childproduct1.1 has sling:resourceType='myproject/common/components/template2

NEW CHANGES:

I have to execute query inside mainproduct1/childproduct1/

So, I have created SubQuery for this as:

private static final String SUB_QUERY = "/jcr:root/content/data/myproject/products//*[@sling:resourceType='myproject/common/components/template2']";

Iterator<Resource> itSubProduct = resourceResolver.findResources(SUB_QUERY, "xpath");

while(itSubProduct.hasNext()) {

              subResource = itsubProduct.next();

              if (null != subResource) {

                parentSubResource = subResource.getParent().getParent();

                Node node = parentSubResource.adaptTo(Node.class);

                if (node.hasNode("jcr:content/main")) {

                  Node dataNode = node.getNode("jcr:content/main");                 

                  if (dataNode.hasProperty("season")) {

                    myVal = dataNode.getProperty("season").getString();

                  }

                }

              }

            }

Now, the problem here I am getting is:

Firstly control enters into first "WHILE" loop, do the processing based upon MAIN_QUERY and once it enters into second "WHILE" loop, it doing the processing for all the child nodes (childproduct1.1, childproduct1.2, childproduct2.1, childproduct2.2)

But I want it to process it only for (childproduct1.1, childproduct1.2) and when the second time it comes then do the processing for (childproduct2.1, childproduct2.2)

I have tried many options but not able to achieve this. Can anyone suggest some options please.

Is there any option to append xPath queries?

private static final String MAIN_QUERY = "/jcr:root/content/data/myproject/products//*[@sling:resourceType='myproject/common/components/template1']";

private static final String SUB_QUERY = "/jcr:root/content/data/myproject/products//*[@sling:resourceType='myproject/common/components/template2']";

like

private static final String SUB_QUERY = MAIN_QUERY + //*[@sling:resourceType='myproject/common/components/template2']";

Any help is much appreciated.

3 Replies

Avatar

Level 7

Hi,

You are getting all the child nodes (childproduct1.1, childproduct1.2, childproduct2.1, childproduct2.2) because of the path under which the query is being executed. Since all of these fall under the path "/jcr:root/content/data/myproject/products" it fetches all resources with sling:resourceType='myproject/common/components/template2.

For the desired result you would need to first make the two while loops nested. Results from MAIN_QUERY would form the outer while loop and the ones we get from SUB_QUERY would be inner while loop. SUB_QUERY now will not be static and final as a part of it representing the search path has to be updated in each iteration.

When you get the resource in each iteration of the outer while loop then the resource's path is to be assigned to String variable SUB_QUERY along with the resourcetype property value as xpath query. Each iteration of the outer while loop gets us the resource under which the SUB_QUERY is to be executed.

With the execution of SUB_QUERY updated in each outer iteration we get the iterator to the required resources(with sling:resourceType = myproject/common/components/template2) which fall under the resource we get in the iteration of outer while loop.

In this way we would get the resources(with sling:resourceType = myproject/common/compo nents/template2) under each mainproduct node in different iterations of outer while loop.

Hope this helps!

Regards,

TechAspect Solutions

Avatar

Level 3

Yes. This is the issue but as you suggested I have already created two while loops. Outer (MAIN_QUERY) and Inner (SUB_QUERY).

But once control is in SUB_QURY while loop, it's getting processed for all the nodes where with sling:resourceType = myproject/common/compo nents/template2).

Could you please share some snippet, if possible how to handle this scenario?

Many Thanks.