Hi Tim,

I've taken a quick look at it, and at first sight, it seems to be a problem with the Jaxen Pattern class which doesn't seem to use the NamespaceContext correctly. I'll investigate this further when I find some time, but I'm hoping someone with a bit more Jaxen/XPath experience can sort this out before that ...

regards,
Maarten


Tim Tool-Man Taylor wrote:

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





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