Правило Dom4j не соответствует всем ожидаемым узлам - PullRequest
2 голосов
/ 03 мая 2009

Я использую API правил dom4j для запуска действия, если предопределенный шаблон // authorize соответствует элементу в следующем фрагменте xml.

        <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>

К сожалению, похоже, что он не работает с вложенными элементами, найдены только элементы авторизации на первом уровне. Действие запускается только два раза, но есть 5 элементов авторизации. У кого-нибудь есть идеи, как решить эту проблему? Заранее спасибо.

Я пытался сопоставить тег авторизации со следующим правилом:

 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);

Правило совпадает два раза на элементах на первом уровне. Я перекрестно проверил шаблон XPath с помощью метода document.selectNodes и получил все пять элементов.

Ответы [ 2 ]

2 голосов
/ 03 мая 2009

У ваших правил есть эта строка?

stylesheet.applyTemplates(node);

Помните, что ваши правила управляют спуском в более глубокие элементы.

Кажется, что шаблоны используются не для выбора элементов, а для проверки соответствия этих элементов при прохождении дерева. Если элемент соответствует шаблону, ваше действие вызывается, но вы обязаны продолжить работу с дочерними элементами. Если нет, дочерние элементы пропускаются.

(Отказ от ответственности: моё понимание может быть неправильным, я не использую dom4j, а просто посмотрел на кулинарную книгу ).

1 голос
/ 04 мая 2009

Я думаю Питер прибил вопрос ; Я просто строю поверх его ответа.

Эта строка в примере кода Томаса немного запутала:

 authorizationRule.setAction( new AuthorizationRule() );

... если AuthorizationRule не является пользовательской реализацией Action , потому что это то, что принимает setAction.

В любом случае, со следующим кодом метод run действия действительно вызывается для каждых пяти элементов «authorize»:

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

final Stylesheet stylesheet = new Stylesheet();                                 
authorizationRule.setAction(new Action(){
    public void run(Node node) throws Exception {
       stylesheet.applyTemplates(node);
    }
 });

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

(Работает только после изменения фрагмента XML на правильно сформированный документ.)

То, как вам нужно использовать таблицу стилей внутри действия, кажется немного неловким, и я не уверен, как это можно сделать в dom4j. Жаль, что соответствующие классы, такие как Таблица стилей и Правило , кажутся довольно неадекватно документированными. (Рассмотрим, например, метод run(Node node, String mode), параметр режима которого, по-видимому, полностью не объясняется.)

...