# Querying by node name

**URL:** <https://community.bloomreach.com/t/querying-by-node-name/3300>\
**Category:** Experience Manager (PaaS/OnPrem)\
**Created:** [July 18, 2022, 11:39pm UTC](https://community.bloomreach.com/t/querying-by-node-name/3300 "2022-07-18T23:39:33Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![itGumby](https://yyz1.discourse-cdn.com/flex027/user_avatar/community.bloomreach.com/itgumby/32/1326_2.png) [@itGumby](https://community.bloomreach.com/u/itGumby)\
**Post date:** [July 18, 2022, 11:39pm UTC](https://community.bloomreach.com/t/querying-by-node-name/3300/1 "2022-07-18T23:39:33Z")

</div>

I have a need to query documents by their node name. We are using the HstQueryBuilder and it works fine where the node name starts with a letter:

```auto
HstQuery getByName(HstRequestContext context, String name) {
    String expression = String.format("fn:name()='%s'", name);
    HippoBean folder = context.getSiteContentBaseBean();
    
    return HstQueryBuilder.create(folder).ofTypes(HippoBean.class)
        .where(constraint(".").jcrExpression(expression)
        .limit(2).build();
}

```

Consider I have documents “top-8-rules” and “8-simple-rules”

builds an XPath query that looks like:

```auto
//element(*,myproject:basedocument)[(@hippo:paths='9db2d725-d54e-4331-81de-275d8ce158e4') and (@hippo:availability='live') and not(@jcr:primaryType='nt:frozenNode') and (fn:name()='top-8-rules')]

```

which works fine. However, when the name is “8-simple-rules”, the corresponding query doesn’t find the document.

Using the /cms/repository, can test several queries:

- works: //element(\*, cmsarchetype:contentdocument)[fn:name()=‘top-8-rules’]
- fails: //element(\*, cmsarchetype:contentdocument)[fn:name()=‘8-simple-rules’]
- works (but isn’t what HstQueryBuilder creates): //top-8-rules[@hippo:availability=‘live’]
- also works: //8-simple-rules[@hippo:availability=‘live’]

Are there other JCR expressions we can use than **fn:name() = {value}**? Or should I build my query with a different API?

---

<div class="post-metadata">

**Author:** ![machak](https://yyz1.discourse-cdn.com/flex027/user_avatar/community.bloomreach.com/machak/32/1298_2.png) [@machak](https://community.bloomreach.com/u/machak)\
**Post date:** [July 19, 2022, 11:14am UTC](https://community.bloomreach.com/t/querying-by-node-name/3300/2 "2022-07-19T11:14:57Z")

</div>

Node names starting with a number must be encoded properly.  
You can use org.hippoecm.repository.api.NodeNameCodec utility class for this

---

<div class="post-metadata">

**Author:** ![itGumby](https://yyz1.discourse-cdn.com/flex027/user_avatar/community.bloomreach.com/itgumby/32/1326_2.png) [@itGumby](https://community.bloomreach.com/u/itGumby)\
**Post date:** [July 19, 2022, 3:50pm UTC](https://community.bloomreach.com/t/querying-by-node-name/3300/3 "2022-07-19T15:50:37Z")

</div>

Thank you, that encoding looks unusual but promising.

---

<div class="post-metadata">

**Author:** ![itGumby](https://yyz1.discourse-cdn.com/flex027/user_avatar/community.bloomreach.com/itgumby/32/1326_2.png) [@itGumby](https://community.bloomreach.com/u/itGumby)\
**Post date:** [July 19, 2022, 9:49pm UTC](https://community.bloomreach.com/t/querying-by-node-name/3300/4 "2022-07-19T21:49:37Z")

</div>

I discovered NodeNameCodec.java doesn’t behave as advertised. ☹

However, I did find a java method that DOES work that is part of the distribution: `org.apache.jackrabbit.util.ISO9075.encode(name)`

```auto
import org.hippoecm.repository.api.NodeNameCodec
import spock.lang.Specification
import spock.lang.Unroll

class NameEncodingSpec extends Specification {

    //@Unroll
    def "NodeNameCodec should encode #name to #value"() {
        expect:
        value == NodeNameCodec.encode(name)

        where:
        name | value
        'top-8-rules' | 'top-8-rules'
        '8-simple-rules' | '_x0038_-simple-rules' // FAILS
    }

    @Unroll
    def "jackrabbit encoding #name to #value"() {
        expect:
        value == org.apache.jackrabbit.util.ISO9075.encode(name)

        where:
        name | value
        'top-8-rules' | 'top-8-rules'
        '8-simple-rules' | '_x0038_-simple-rules'
        'a' | 'a'
        '8' | '_x0038_'
        'ab' | 'ab'
        'abc' | 'abc'
        'abc-123' | 'abc-123'
        '123-abc' | '_x0031_23-abc'
    }
}

```

---

<div class="post-metadata">

**Author:** ![itGumby](https://yyz1.discourse-cdn.com/flex027/user_avatar/community.bloomreach.com/itgumby/32/1326_2.png) [@itGumby](https://community.bloomreach.com/u/itGumby)\
**Post date:** [July 20, 2022, 4:09pm UTC](https://community.bloomreach.com/t/querying-by-node-name/3300/5 "2022-07-20T16:09:13Z")

</div>

I heard from other sources the `NodeNameCode` was designed to handle encoding nodes with namespaces in their name, such as `myproject:8-simple-rules`. Instead the jackrabbit method is appropriate for my case.
