I'm having difficulty using Rules with XPath patterns to select 
attributes that have a namespace prefix.

The example document:

    <div xmlns:max='http://tool-man.org/max'>
        <aaa headroom='blip'/>
        <bbb/>
        <ccc max:headroom='vert'/>
    </div>

The XPath queries:

    W:    //@headroom
    X:    //[EMAIL PROTECTED]
    Y:    //@max:headroom
    Z:    //[EMAIL PROTECTED]:headroom]

I'm trying to create two rules, one that matches only the max:headroom 
attribute and another that matches any element with a max:headroom 
attribute.  The behavior when using Rules and XPath patterns is 
different than the behavior I would expected based on what selectNodes
() returns.  I've included a failing unit test at the end of this 
message that either demonstrates a bug or my own misunderstandings.

Given the document and queries above, I would expect each query to 
match a single node.  Creating a Document and calling doc.selectNodes() 
confirms my expectation, i.e. calling doc.selectNodes("//@headroom") 
returns a list containing only the headroom='blip' attribute.

However, I get unexpected behavior when using the same XPath queries as 
patterns for stylesheet rules.  Using the following pattern matches 
both headroom and max:headroom attributes:

    Pattern pattern = DocumentHelper.createPattern("//@headroom");

Even more suprising, createPattern("//@max:headroom") also matches both 
attributes.

Please elucidate me :)

Thanks,
Tim


In the following test case, only test_directXPathQueries() passes:

=======================================================================
import java.util.ArrayList;
import java.util.List;

import junit.framework.TestCase;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.rule.Action;
import org.dom4j.rule.Rule;
import org.dom4j.rule.Stylesheet;

public class _TestXPathWithNamespaces extends TestCase {

    private Document doc;
    private Element aaa;
    private Element ccc;
    private Stylesheet stylesheet;
    private _MockRule ruleW;
    private _MockRule ruleY;
    private _MockRule ruleX;
    private _MockRule ruleZ;

    public void test_directXPathQueries() throws Exception {
        assertEquals(1, doc.selectNodes("//@headroom").size());
        assertEquals(1, doc.selectNodes("//@max:headroom").size());
        assertEquals(1, doc.selectNodes("//[EMAIL PROTECTED]").size());
        assertEquals(1, doc.selectNodes("//[EMAIL PROTECTED]:headroom]").size());

        assertEquals(aaa.attribute(0), doc
                .selectSingleNode("//@headroom"));
        assertEquals(ccc.attribute(0), doc
                .selectSingleNode("//@max:headroom"));

        assertEquals(aaa, doc.selectSingleNode("//[EMAIL PROTECTED]"));
        assertEquals(ccc, doc.selectSingleNode("//[EMAIL PROTECTED]:headroom]"));
    }

    public void test_xPathStylesheetRules_1() throws Exception {
        stylesheet.addRule(ruleW);
        stylesheet.addRule(ruleX);

        stylesheet.run(doc);
        assertEquals(doc.selectNodes("//@headroom"),
                ruleW.matchingNodes);
        assertEquals(doc.selectNodes("//[EMAIL PROTECTED]"),
                ruleX.matchingNodes);
    }

    public void test_xPathStylesheetRules_2() throws Exception {
        stylesheet.addRule(ruleY);
        stylesheet.addRule(ruleZ);

        stylesheet.run(doc);
        assertEquals(doc.selectNodes("//@max:headroom"),
                ruleY.matchingNodes);
        assertEquals(doc.selectNodes("//[EMAIL PROTECTED]:headroom]"),
                ruleZ.matchingNodes);
    }

    public void test_xPathStylesheetRules_3() throws Exception {
        stylesheet.addRule(ruleW);
        stylesheet.addRule(ruleX);
        stylesheet.addRule(ruleY);
        stylesheet.addRule(ruleZ);

        stylesheet.run(doc);
        assertEquals(doc.selectNodes("//@headroom"),
                ruleW.matchingNodes);
        assertEquals(doc.selectNodes("//[EMAIL PROTECTED]"),
                ruleX.matchingNodes);
        assertEquals(doc.selectNodes("//@max:headroom"),
                ruleY.matchingNodes);
        assertEquals(doc.selectNodes("//[EMAIL PROTECTED]:headroom]"),
                ruleZ.matchingNodes);
    }

    protected void setUp() throws Exception {
        super.setUp();

        doc = DocumentHelper
                .parseText("<div xmlns:max='http://tool-man.org/max'>"
                        + "<aaa headroom='blip'/>" + "<bbb/>"
                        + "<ccc max:headroom='vert'/>" + "</div>");

        aaa = (Element) doc.selectSingleNode("/div/aaa");
        ccc = (Element) doc.selectSingleNode("/div/ccc");

        ruleW = new _MockRule("//@headroom");
        ruleX = new _MockRule("//[EMAIL PROTECTED]");
        ruleY = new _MockRule("//@max:headroom");
        ruleZ = new _MockRule("//[EMAIL PROTECTED]:headroom]");

        stylesheet = new Stylesheet();
    }

    private final class _MockRule extends Rule {
        protected List matchingNodes;

        _MockRule(String xPathPattern) {
            this.matchingNodes = new ArrayList();
            setPattern(DocumentHelper.createPattern(xPathPattern));
            setAction(new Action() {
                public void run(Node node) throws Exception {
                    matchingNodes.add(node);
                    stylesheet.applyTemplates(node);
                }
            });
        }
    }
}


-------------------------------------------------------
This SF.Net email is sponsored by: SourceForge.net Broadband
Sign-up now for SourceForge Broadband and get the fastest
6.0/768 connection for only $19.95/mo for the first 3 months!
http://ads.osdn.com/?ad_id=2562&alloc_id=6184&op=click
_______________________________________________
dom4j-dev mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/dom4j-dev

Reply via email to