tomcat-taglibs-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Flavio Tordini <f.tord...@kataweb.it>
Subject Re: using Node variables with JSTL XML tags
Date Thu, 09 Sep 2004 16:19:25 GMT
ok, i filed the bug:
http://issues.apache.org/bugzilla/show_bug.cgi?id=31147

Kris, thank you so much for your help!

flavio

Kris Schneider wrote:
> I took a quick look at the code as well and it seems like what you're suggesting
> should work. In other words, if it's not a Document and it's not a
> JSTLNodeList, but it is a Node, do this:
> 
> Document doc = getDummyDocumentWithoutRoot();
> Node importedNode = doc.importNode((Node)varObject, true);
> doc.appendChild(importedNode);
> boundDocument = doc;
> if (whetherOrigXPath) {
>     xpath = "/*" + xpath;
> }
> 
> instead of the current:
> 
> boundDocument = (Node)varObject;
> 
> At this point, the best thing to do would be to file a bug report:
> 
> http://issues.apache.org/bugzilla/enter_bug.cgi?product=Taglibs
> 
> Quoting Flavio Tordini <f.tordini@kataweb.it>:
> 
> 
>>hi Kris,
>>I think Xalan does the right thing evaluating
>>
>>nodes = XPathAPI.selectNodeList(node, "/@name");
>>
>>starting from the document root. The real problem is not being able to 
>>make *relative* XPath queries (without the starting slash). This seems 
>>to be a major flaw in the JSTL spec.
>>
>>Since node variables set with x:set (obviously) work, I looked at the 
>>Jakarta impl sources to discover how x:set does the job. Basically it's 
>>a big *hack*:
>>
>>- x:set evaluates the XPath expression with Xalan the wraps the Nodelist 
>>result into a org.apache.taglibs.standard.tag.common.xml.JSTLNodeList class.
>>
>>- when x:out evaluates the XPath expression it checks for the $variable 
>>type:
>>   - if it is a JSTLNodeList containing 1 element of type 	 
>>org.w3c.dom.Node, it creates a new Document, imports the Node and then 
>>       (here comes the hack) it prepends "/*" to the user specified XPath:
>>
>>xpath="/*" + xpath;
>>(org.apache.taglibs.standard.tag.common.xml.XPathUtil line 683)
>>
>>   - if the $variable is a org.w3.dom.Node it is used as it is as the 
>>XPath Context as expected.
>>
>>why this different treatment? obviously because of the Xalan behaviour 
>>that Kris explained. I think the same hack should be applied to Node 
>>variables so they work just like the impl-specific JSTLNodeList.
>>
>>Any ideas? Any chance to let the developers know? They don't seem to be 
>>on this list at all...
>>
>>flavio
>>
>>
>>
>>
>>Kris Schneider wrote:
>>
>>>It seems like an issue with Xalan's XPath implementation. The Standard 1.1
>>>taglib uses Xalan while Standard 1.0 uses Jaxen/SAXPath. Here's an example
>>
>>app
>>
>>>that mimics what it sounds like Flavio is trying to do:
>>>
>>>import java.io.*;
>>>import javax.xml.parsers.*;
>>>import org.apache.xpath.*;
>>>import org.w3c.dom.*;
>>>import org.xml.sax.*;
>>>
>>>public class XPathNode {
>>>
>>>    private static final String XML =
>>>        "<root name=\"root\"><child name=\"child\"><grandchild
>>>name=\"grandchild\"></grandchild></child></root>";
>>>
>>>    public static void main(String[] args) throws Exception {
>>>        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
>>>        DocumentBuilder db = dbf.newDocumentBuilder();
>>>        Document doc = db.parse(new InputSource(new StringReader(XML)));
>>>        Element root = doc.getDocumentElement();
>>>        Node node = root.getFirstChild();
>>>        NodeList nodes = null;
>>>
>>>        nodes = XPathAPI.selectNodeList(doc, "/root/child/@name");
>>>        printNodes(nodes);
>>>
>>>        nodes = XPathAPI.selectNodeList(node, "/@name");
>>>        printNodes(nodes);
>>>
>>>        nodes = XPathAPI.selectNodeList(node, "./@name");
>>>        printNodes(nodes);
>>>    }
>>>
>>>    public static void printNodes(NodeList nodes) {
>>>        System.out.println("nodes:");
>>>        for (int i = 0, n = nodes.getLength(); i < n; i++) {
>>>            Node node = nodes.item(i);
>>>            System.out.println("\t" + node);
>>>        }
>>>    }
>>>}
>>>
>>>Which results in:
>>>
>>>nodes:
>>>    name="child"
>>>nodes:
>>>nodes:
>>>    name="child"
>>>
>>>Notice that for the XPath evaluation to work with "node", I had to prepend
>>
>>"."
>>
>>>to the expression. I'm not sure if it's possible to construct something
>>
>>similar
>>
>>>with the "select" attribute of JSTL's x tags...
>>>
>>>Quoting "Johnson, Chris" <chrisjohnson@ti.com>:
>>>
>>>
>>>
>>>>I see.  I ran across a similar problem with JDOM Xpath, although they
>>>>solved it in a newer version, but totally screwed up the API and some
>>>>other stuff, so it killed the fix for me.
>>>>
>>>>I had performance problems with the xml jstl tags (forEach), so I've
>>>>since moved on to using xslt.  They're clearly not in a big hurry to fix
>>>>these (what we would consider big) problems.
>>>>
>>>>Chris
>>>>
>>>>-----Original Message-----
>>>>From: Flavio Tordini [mailto:f.tordini@kataweb.it] 
>>>>Sent: Wednesday, September 08, 2004 10:36 AM
>>>>To: Tag Libraries Users List
>>>>Subject: Re: using Node variables with JSTL XML tags
>>>>
>>>>
>>>>hi chris,
>>>>thank you for your answer. The problem is i'm actually passing a *Node* 
>>>>to the tag, not a Document. So I'd like to evaluate the XPath starting 
>>>
>>>>from that Node, not from the root of the Document the Node belongs to.
>>>
>>>>I also tried:
>>>><x:forEach select="$node">
>>>>  <x:out select="@name"/>
>>>></x:forEach>
>>>>
>>>>and it works. But it's kind of a hack. I'm not searching for a 
>>>>workaround, I need a clean solution since i'm working on a project that 
>>>>aims to simplify JSP development with the aid of the JSTL + plus a 
>>>>custom Servlet, and I cannot expect people to use this "forEach" hack.
>>>>
>>>>flavio
>>>>
>>>>Johnson, Chris wrote:
>>>>
>>>>
>>>>>It seems that what 1.1 is doing is more correct.
>>>>>
>>>>>How do you expect jstl to find your sub node without telling it how to
>>>>
>>>>>get there?  That's how it works in directories on a computer (unix or

>>>>>pc).  The only way that I know of to go to a subnode without providing
>>>>
>>>>>the full path is by using the // operator, like: 
>>>>>select="$doc//subnode". Otherwise, the only way (that I know of) to 
>>>>>"cd" to a subnode, and therefore not have to give the full path is by

>>>>>using x:forEach.
>>>>>
>>>>>Chris
>>>>>
>>>>>-----Original Message-----
>>>>>From: Flavio Tordini [mailto:f.tordini@kataweb.it]
>>>>>Sent: Wednesday, September 08, 2004 9:37 AM
>>>>>To: Tag Libraries Users List
>>>>>Subject: Re: using Node variables with JSTL XML tags
>>>>>
>>>>>
>>>>>hi all,
>>>>>In the list archive, I found that the same question has been asked in
>>>>>June e never answered:
>>>>>
>>>>>http://www.mail-archive.com/taglibs-user@jakarta.apache.org/msg07315.h
>>>>>tm
>>>>>l
>>>>>
>>>>>should I post to the dev mailing list?
>>>>>should I report a bug?
>>>>>
>>>>>please someone answer!
>>>>>
>>>>>flavio
>>>>>
>>>>>Flavio Tordini wrote:
>>>>>
>>>>>
>>>>>
>>>>>>hi all,
>>>>>>I'm experimenting with the JSTL XML tags. I have a org.w3c.dom.Node

>>>>>>variable and I'm trying to use the JSTL with it. Something like:
>>>>>>
>>>>>><x:out select="$node/@name"/>
>>>>>>
>>>>>>The odd thing is that the XPath expression is evaluated relative the

>>>>>>document root, not to the specified node. The following works:
>>>>>>
>>>>>><x:out select="$node/full/path/to/node/@name"/>
>>>>>>
>>>>>>I cannot find an explanation in the JSTL 1.1 spec. The only thing
I 
>>>>>>found is in section 11.1.3:
>>>>>>
>>>>>>"An XPath expression must also treat variables that resolve to 
>>>>>>implementations of standard DOM interfaces as representing nodes of
>>>>>
>>>>>the
>>>>>
>>>>>
>>>>>
>>>>>>type bound to that interface by the DOM specification."
>>>>>>
>>>>>>Is this behaviour by design? Is it compliant with the spec?
>>>>>>
>>>>>>Thank you in advance,
>>>>>>flavio
> 
> 

---------------------------------------------------------------------
To unsubscribe, e-mail: taglibs-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: taglibs-user-help@jakarta.apache.org


Mime
View raw message