Search code examples
javaxmlxsltdom4j

Dom4j rule does not match all expected nodes


I'm using dom4j's rules api to fire an action if the predefined pattern //authorize matches an element in the following xml snippet.

        <authorize role_required="admin">
        <node title="node which is visible only to admin" path="" >
            <authorize role_required="admin">
                <node title="node which is visible only to admin" path=""/>
            </authorize>
            <authorize role_required="admin">
                <node title="node which is visible only to admin" path="">
                    <authorize role_required="admin">
                    </authorize>
                        <node title="node which is visible only to admin" path=""/>
                </node>
            </authorize>
        </node>
    </authorize>
    <authorize role_deny="admin">
        <node title="Node which is not visible to admin" path=""/>
    </authorize>

Unfortunately it seems that it doesn't work with nested elements, only the authorize elements on the first level are found. The action is triggered only two times, but there are 5 authorize elements. Does anybody have an idea how to solve this problem? Thanks in advance.

I've tried to match the authorize tag with the following rule:

 Rule authorizationRule = new Rule();
 authorizationRule.setPattern( DocumentHelper.createPattern( "//authorize" ) );
 authorizationRule.setAction( new AuthorizationRule() );

this.stylesheet = new Stylesheet();

this.stylesheet.addRule(authorizationRule);
this.stylesheet.run(document);

The rule matches two times on the elements on the fist level. I cross checked the XPath pattern with the document.selectNodes method and got all five elements.


Solution

  • Do your rules have this line?

    stylesheet.applyTemplates(node);
    

    Remember that your rules control descent into deeper elements.

    It seems that patterns are not used for selecting elements, but for checking that element matches when going through the tree. If element matches the pattern, your action is called, but it's your responsibility to continue in child elements. If you don't, child elements are skipped.

    (Disclaimer: My understanding may be wrong, I don't use dom4j, and just looked at cookbook).