... <%@ page import="org.apache.commons.jxpath.ri.*" %> <%@ page import="org.apache.commons.jxpath.ri.model.*" %> ... <% JXPathContext domCtx = JXPathContext.newContext(dom); NodePointer childPtr = (NodePointer)domCtx.getPointer("root/child"); NodePointer idPtr = childPtr.createAttribute(domCtx, new QName("id")); idPtr.setValue("1"); %> ...
Mark R. Diggory wrote:
I believe you would get the parent element of the attribute and use a pointer to that Node to add the attribute. Look Over DOMNodePointer for more details.
http://jakarta.apache.org/commons/jxpath/apidocs/org/apache/commons/jxpath/ri/model/dom/DOMNodePointer.html
-Mark
Kris Schneider wrote:
That still doesn't seem to address the question about adding an attribute. If
the attribute doesn't exist, you can't access it with something like
domCtx.getPointer("root/child/@id"), right? I took a look at the API and this
seemed to work (JSTL 1.1, Xalan 2.6.0, and Xerces 2.6.2 on TC 5.0.19):
<%@ page contentType="text/plain" %> <%@ page import="org.apache.commons.jxpath.*" %> <%@ page import="org.w3c.dom.*" %> <%@ taglib prefix="x" uri="http://java.sun.com/jsp/jstl/xml" %>
<x:parse varDom="dom"> <root> <child>Child 1</child> <child>Child 2</child> <child>Child 3</child> </root> </x:parse>
child: <x:out select="$dom/root/child"/> child id: <x:out select="$dom/root/child/@id"/>
<jsp:useBean id="dom" type="org.w3c.dom.Document"/> <% JXPathContext domCtx = JXPathContext.newContext(dom); Pointer ptr = domCtx.getPointer("root/child"); Element elem = (Element)ptr.getNode(); elem.setAttribute("id", "1"); %>
child: <x:out select="$dom/root/child"/> child id: <x:out select="$dom/root/child/@id"/>
Which produced:
child: Child 1 child id: child: Child 1 child id: 1
It looks like there's also a way to add an attribute through the JXPath API, but
you have to cast the Pointer to a NodePointer and the code's a bit uglier. Of
course, if you're gonna drop down to Java, there are lots of other options for
programmatically modifying DOM through XPath...
Quoting "Mark R. Diggory" <[EMAIL PROTECTED]>:
You can use JXPath to manipulate the content of the DOM directly (ie without having to instantiate a whole new copied DOM object to establish your changes (as you whould have to do with XSLT).
Say you instantiate some DOM Document object, you can use JXPath as such:
Document doc = ....; JXPathContext context = JXPathContext.newContext(doc);
Iterator iter = context.iteratePointers("//some[xpath]"); while (iter.hasNext()) { Pointer pointer = (Pointer) iter.next(); System.out.println("value before change: " + pointer.getValue()); pointer.setValue(value); System.out.println("value after change: " + pointer.getValue()); }
.. Serialize your DOM to wherever using whatever.
Yes, by scriptable, I mean you can write your java code between <%%> or <jsp:scriptlet></jsp:scriptlet>
Maybe someday there'll be a JXPath taglibrary which would make all this all grovy in JSP.
-Mark
Kris Schneider wrote:
I'm not too familiar with JXPath, and I'm sure it's useful in other
contexts,
but I don't see how it's applicable to Murray's problem. Can it be used to
add
an attribute to an existing element? I'm also not sure I get the point
about
"JXPath can be scripted into a JSP". Do you mean something besides:
<% Foo fooCtx = (Foo)JXPathContext.newContext(myFoo); %>
Quoting "Mark R. Diggory" <[EMAIL PROTECTED]>:
This is outside the scope of the taglibrary, JSTL xml taglibrary is for presentation of xml content, not for its manipulation. I recommend looking into a package such as JXPath to accomplish manipulation of the content of a DOM object. the nice thing is that JXPath can be scripted into a JSP, Servlet or Struts Action, which gives you the fredom to move it out of the Presentation layer (where you probibly shouldn't be placing such logic).
http://jakarta.apache.org/commons/jxpath/
Good Luck -Mark
Murray Lang wrote:
Hi
I've been using the XML tags in JSTL and found them very useful, however now I need to add an attribute to an XML element and have hit a brick wall.
I've tried using <c:set> and EL, treating a DOM object as a bean, but the DOM interface is implementation-dependent and my implementation (xerces) doesn't lend itself to adding attributes with the simple EL view of bean properties.
It seems to me that <x:set> needs to have a "target"attribute along the same lines as <c:set>, but accepting an XPath expression.
eg
<x:set select="12345" target="$myRoot//myElement[position()=0]/@myAttribute" />
where:
- select can be either an XPath expression or an immediate value.
- if @myAttribute doesn't currently exist in the element then it is created.
Does this make sense?
Is there a simple, portable, way of achieving this using JSTL as it stands? (Using <c:set> is not portable due to DOM being implementation dependent).
Thanks Murray
-- Kris Schneider <mailto:[EMAIL PROTECTED]> D.O.Tech <http://www.dotech.com/>
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]