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