You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by dm...@apache.org on 2002/10/13 04:59:02 UTC
cvs commit: jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/model/dom DOMNodePointer.java
dmitri 2002/10/12 19:59:02
Modified: jxpath/src/java/org/apache/commons/jxpath/ri/axes
SimplePathInterpreter.java
jxpath/src/java/org/apache/commons/jxpath/ri/compiler
Path.java
jxpath/src/java/org/apache/commons/jxpath/ri/model/beans
NullPropertyPointer.java BeanAttributeIterator.java
jxpath/src/java/org/apache/commons/jxpath/ri/model
NodePointer.java
jxpath/src/java/org/apache/commons/jxpath/ri/model/jdom
JDOMNodePointer.java
jxpath/src/java/org/apache/commons/jxpath/ri/model/dom
DOMNodePointer.java
Log:
1. Now bean's properties can be accessed either with the child:: or the attribute:: axis.
2. Missing attributes can be created with an AbstractFactory
Revision Changes Path
1.7 +60 -29 jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/axes/SimplePathInterpreter.java
Index: SimplePathInterpreter.java
===================================================================
RCS file: /home/cvs/jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/axes/SimplePathInterpreter.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- SimplePathInterpreter.java 10 Aug 2002 01:35:47 -0000 1.6
+++ SimplePathInterpreter.java 13 Oct 2002 02:59:01 -0000 1.7
@@ -119,7 +119,7 @@
* starts with the given root, which is the result of evaluation
* of the root expression of the expression path, applies the
* given predicates to it and then follows the given steps.
- * All steps must have the axis "child::"
+ * All steps must have the axis "child::" or "attribute::"
* and a name test. They can also optionally have predicates
* of type [@name=...] or simply [...] interpreted as an index.
*/
@@ -204,17 +204,7 @@
Step[] steps, int current_step)
{
Step step = steps[current_step];
- NodePointer childPointer;
- if (step.getAxis() == Compiler.AXIS_CHILD){
- // Treat the name test as a property name
- QName name = ((NodeNameTest)step.getNodeTest()).getNodeName();
-
- childPointer = parentPointer.getPropertyPointer();
- ((PropertyPointer)childPointer).setPropertyName(name.toString());
- }
- else {
- childPointer = parentPointer;
- }
+ NodePointer childPointer = createChildPointerForStep(parentPointer, step);
if (!childPointer.isActual()){
// The property does not exist - create a null pointer.
@@ -272,10 +262,14 @@
Step[] steps, int current_step)
{
Step step = steps[current_step];
+
+ if (step.getAxis() == Compiler.AXIS_SELF){
+ return doStep(context, parentPointer, steps, current_step + 1);
+ }
+
int bestQuality = 0;
NodePointer bestMatch = null;
- NodeIterator it =
- parentPointer.childIterator(step.getNodeTest(), false, null);
+ NodeIterator it = getNodeIterator(parentPointer, step);
if (it != null){
for (int i = 1; it.setPosition(i); i++){
NodePointer childPointer = it.getNodePointer();
@@ -316,15 +310,8 @@
Step step = steps[current_step];
Expression predicates[] = step.getPredicates();
- NodePointer childPointer;
- if (step.getAxis() == Compiler.AXIS_CHILD){
- QName name = ((NodeNameTest)step.getNodeTest()).getNodeName();
- childPointer = parentPointer.getPropertyPointer();
- ((PropertyPointer)childPointer).setPropertyName(name.toString());
- }
- else {
- childPointer = parentPointer;
- }
+ NodePointer childPointer =
+ createChildPointerForStep(parentPointer, step);
if (!childPointer.isActual()){
// Property does not exist - return a null pointer
return createNullPointer(
@@ -336,6 +323,28 @@
context, childPointer, steps, current_step, predicates, 0);
}
+ private static NodePointer createChildPointerForStep(
+ PropertyOwnerPointer parentPointer, Step step)
+ {
+ int axis = step.getAxis();
+ if (axis == Compiler.AXIS_CHILD || axis == Compiler.AXIS_ATTRIBUTE){
+ NodePointer childPointer;
+ QName name = ((NodeNameTest)step.getNodeTest()).getNodeName();
+ if (axis == Compiler.AXIS_ATTRIBUTE && isLangAttribute(name)){
+ childPointer = new LangAttributePointer(parentPointer);
+ }
+ else {
+ childPointer = parentPointer.getPropertyPointer();
+ ((PropertyPointer)childPointer).setPropertyName(name.toString());
+ childPointer.setAttribute(axis == Compiler.AXIS_ATTRIBUTE);
+ }
+ return childPointer;
+ }
+ else {
+ return parentPointer;
+ }
+ }
+
/**
* A path that starts with a standard InfoSet node, e.g. a DOM Node.
* The method evaluates the first predicate in a special way and
@@ -348,7 +357,8 @@
Step step = steps[current_step];
Expression predicates[] = step.getPredicates();
- if (step.getAxis() == Compiler.AXIS_SELF){
+ int axis = step.getAxis();
+ if (axis == Compiler.AXIS_SELF){
return doPredicate(context, parent,
steps, current_step, predicates, 0);
}
@@ -361,8 +371,7 @@
// It is a very common use case, so it deserves individual
// attention
if (predicates.length == 1){
- NodeIterator it = parent.childIterator(
- step.getNodeTest(), false, null);
+ NodeIterator it = getNodeIterator(parent, step);
NodePointer pointer = null;
if (it != null){
if (predicate instanceof NameAttributeTest){ // [@name = key]
@@ -387,8 +396,7 @@
}
}
else {
- NodeIterator it = parent.childIterator(
- step.getNodeTest(), false, null);
+ NodeIterator it = getNodeIterator(parent, step);
if (it != null){
List list = new ArrayList();
for (int i = 1; it.setPosition(i); i++){
@@ -686,10 +694,12 @@
Step step = steps[current_step];
- if (step.getAxis() == Compiler.AXIS_CHILD){
+ int axis = step.getAxis();
+ if (axis == Compiler.AXIS_CHILD || axis == Compiler.AXIS_ATTRIBUTE){
NullPropertyPointer pointer = new NullPropertyPointer(parent);
QName name = ((NodeNameTest)step.getNodeTest()).getNodeName();
pointer.setPropertyName(name.toString());
+ pointer.setAttribute(axis == Compiler.AXIS_ATTRIBUTE);
parent = pointer;
}
// else { it is self::node() }
@@ -729,5 +739,26 @@
// Proceed with the remaining steps
return createNullPointer(
context, parent, steps, current_step + 1);
+ }
+
+ private static NodeIterator getNodeIterator(NodePointer pointer, Step step){
+ if (step.getAxis() == Compiler.AXIS_CHILD){
+ return pointer.childIterator(step.getNodeTest(), false, null);
+ }
+ else { // Compiler.AXIS_ATTRIBUTE
+ if (!(step.getNodeTest() instanceof NodeNameTest)){
+ throw new UnsupportedOperationException(
+ "Not supported node test for attributes: " +
+ step.getNodeTest());
+ }
+ return pointer.attributeIterator(
+ ((NodeNameTest)step.getNodeTest()).getNodeName());
+ }
+ }
+
+ private static boolean isLangAttribute(QName name){
+ return name.getPrefix() != null &&
+ name.getPrefix().equals("xml") &&
+ name.getName().equals("lang");
}
}
1.6 +6 -5 jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/compiler/Path.java
Index: Path.java
===================================================================
RCS file: /home/cvs/jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/compiler/Path.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- Path.java 10 Aug 2002 01:39:29 -0000 1.5
+++ Path.java 13 Oct 2002 02:59:01 -0000 1.6
@@ -115,7 +115,8 @@
Compiler.NODE_TYPE_NODE){
accepted = true;
}
- else if (steps[i].getAxis() == Compiler.AXIS_CHILD &&
+ else if ((steps[i].getAxis() == Compiler.AXIS_CHILD ||
+ steps[i].getAxis() == Compiler.AXIS_ATTRIBUTE) &&
(steps[i].getNodeTest() instanceof NodeNameTest) &&
!((NodeNameTest)steps[i].getNodeTest()).
getNodeName().getName().equals("*")){
1.8 +24 -12 jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/model/beans/NullPropertyPointer.java
Index: NullPropertyPointer.java
===================================================================
RCS file: /home/cvs/jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/model/beans/NullPropertyPointer.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- NullPropertyPointer.java 10 Aug 2002 16:13:04 -0000 1.7
+++ NullPropertyPointer.java 13 Oct 2002 02:59:01 -0000 1.8
@@ -82,7 +82,7 @@
}
public QName getName(){
- return new QName(null, propertyName);
+ return new QName(propertyName);
}
public void setPropertyIndex(int index){
@@ -101,7 +101,7 @@
}
public NodePointer getValuePointer(){
- return new NullPointer(this, new QName(null, getPropertyName()));
+ return new NullPointer(this, new QName(getPropertyName()));
}
protected boolean isActualProperty(){
@@ -122,19 +122,31 @@
}
public NodePointer createPath(JXPathContext context){
- return parent.createChild(context, getName(), getIndex());
+ if (isAttribute()){
+ return parent.createAttribute(context, getName());
+ }
+ else {
+ return parent.createChild(context, getName(), getIndex());
+ }
}
public NodePointer createPath(JXPathContext context, Object value){
- return parent.createChild(context, getName(), getIndex(), value);
+ if (isAttribute()){
+ NodePointer pointer = parent.createAttribute(context, getName());
+ pointer.setValue(value);
+ return pointer;
+ }
+ else {
+ return parent.createChild(context, getName(), getIndex(), value);
+ }
}
- public NodePointer createChild(JXPathContext context,
+ public NodePointer createChild(JXPathContext context,
QName name, int index, Object value){
return createPath(context).createChild(context, name, index, value);
}
- public NodePointer createChild(JXPathContext context,
+ public NodePointer createChild(JXPathContext context,
QName name, int index){
return createPath(context).createChild(context, name, index);
}
@@ -184,13 +196,13 @@
private String escape(String string){
int index = string.indexOf('\'');
while (index != -1){
- string = string.substring(0, index) + "'" +
+ string = string.substring(0, index) + "'" +
string.substring(index + 1);
index = string.indexOf('\'');
}
index = string.indexOf('\"');
while (index != -1){
- string = string.substring(0, index) + """ +
+ string = string.substring(0, index) + """ +
string.substring(index + 1);
index = string.indexOf('\"');
}
1.3 +34 -13 jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/model/beans/BeanAttributeIterator.java
Index: BeanAttributeIterator.java
===================================================================
RCS file: /home/cvs/jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/model/beans/BeanAttributeIterator.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- BeanAttributeIterator.java 24 Apr 2002 04:06:46 -0000 1.2
+++ BeanAttributeIterator.java 13 Oct 2002 02:59:01 -0000 1.3
@@ -66,24 +66,35 @@
import org.apache.commons.jxpath.ri.model.NodePointer;
/**
- * An iterator of attributes of a JavaBean. Currently supports only one
- * attribute - "lang".
+ * An iterator of attributes of a JavaBean. Returns bean properties as
+ * well as the "xml:lang" attribute.
*
* @author Dmitri Plotnikov
* @version $Revision$ $Date$
*/
-public class BeanAttributeIterator implements NodeIterator {
+public class BeanAttributeIterator extends PropertyIterator {
private NodePointer parent;
- private QName name;
private int position = 0;
+ private boolean includeXmlLang;
- public BeanAttributeIterator(NodePointer parent, QName name){
+ public BeanAttributeIterator(PropertyOwnerPointer parent, QName name){
+ super(parent,
+ (name.getPrefix() == null &&
+ (name.getName() == null || name.getName().equals("*"))) ?
+ null : name.toString(), false, null);
this.parent = parent;
- this.name = name;
+ includeXmlLang =
+ (name.getPrefix() != null && name.getPrefix().equals("xml")) &&
+ (name.getName().equals("lang") || name.getName().equals("*"));
}
public NodePointer getNodePointer(){
- return new LangAttributePointer(parent);
+ if (includeXmlLang && position == 1){
+ return new LangAttributePointer(parent);
+ }
+ else {
+ return super.getNodePointer();
+ }
}
public int getPosition(){
@@ -92,7 +103,17 @@
public boolean setPosition(int position){
this.position = position;
- return position == 1 && name.getPrefix() != null && name.getPrefix().equals("xml") &&
- (name.getName().equals("lang") || name.getName().equals("*"));
+ if (includeXmlLang){
+ if (position == 1){
+ return true;
+ }
+ else {
+ return super.setPosition(position - 1);
+ }
+ }
+ else {
+ this.position = position;
+ return super.setPosition(position);
+ }
}
}
1.11 +86 -43 jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/model/NodePointer.java
Index: NodePointer.java
===================================================================
RCS file: /home/cvs/jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/model/NodePointer.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- NodePointer.java 10 Aug 2002 16:13:03 -0000 1.10
+++ NodePointer.java 13 Oct 2002 02:59:01 -0000 1.11
@@ -91,45 +91,51 @@
public static int WHOLE_COLLECTION = Integer.MIN_VALUE;
protected int index = WHOLE_COLLECTION;
public static String UNKNOWN_NAMESPACE = "<<unknown namespace>>";
+ private boolean attribute = false;
/**
* Allocates an entirely new NodePointer by iterating through all installed
* NodePointerFactories until it finds one that can create a pointer.
*/
public static NodePointer newNodePointer(
- QName name,
- Object bean,
- Locale locale) {
+ QName name, Object bean, Locale locale)
+ {
if (bean == null) {
return new NullPointer(name, locale);
}
NodePointerFactory[] factories =
JXPathContextReferenceImpl.getNodePointerFactories();
for (int i = 0; i < factories.length; i++) {
- NodePointer pointer = factories[i].createNodePointer(name, bean, locale);
+ NodePointer pointer = factories[i].
+ createNodePointer(name, bean, locale);
if (pointer != null) {
return pointer;
}
}
throw new JXPathException(
- "Could not allocate a NodePointer for object of " + bean.getClass());
+ "Could not allocate a NodePointer for object of " +
+ bean.getClass());
}
/**
* Allocates an new child NodePointer by iterating through all installed
* NodePointerFactories until it finds one that can create a pointer.
*/
- public static NodePointer newChildNodePointer(NodePointer parent, QName name, Object bean) {
+ public static NodePointer newChildNodePointer(
+ NodePointer parent, QName name, Object bean)
+ {
NodePointerFactory[] factories =
JXPathContextReferenceImpl.getNodePointerFactories();
for (int i = 0; i < factories.length; i++) {
- NodePointer pointer = factories[i].createNodePointer(parent, name, bean);
+ NodePointer pointer = factories[i].
+ createNodePointer(parent, name, bean);
if (pointer != null) {
return pointer;
}
}
throw new JXPathException(
- "Could not allocate a NodePointer for object of " + bean.getClass());
+ "Could not allocate a NodePointer for object of " +
+ bean.getClass());
}
protected NodePointer parent;
@@ -149,6 +155,20 @@
}
/**
+ * Set to true if the pointer represents the "attribute::" axis.
+ */
+ public void setAttribute(boolean attribute){
+ this.attribute = attribute;
+ }
+
+ /**
+ * Returns true if the pointer represents the "attribute::" axis.
+ */
+ public boolean isAttribute(){
+ return attribute;
+ }
+
+ /**
* Returns true if this Pointer has no parent.
*/
public boolean isRoot() {
@@ -198,7 +218,8 @@
/**
* If the pointer represents a collection (or collection element),
- * returns the length of the collection. Otherwise returns 1 (even if the value is null).
+ * returns the length of the collection.
+ * Otherwise returns 1 (even if the value is null).
*/
public int getLength() {
Object value = getBaseValue();
@@ -232,11 +253,13 @@
* if it is null. A non-actual pointer represents a part that does not exist
* at all.
* For instance consider the pointer "/address/street".
- * If both <em>address</em> and <em>street</em> are not null, the pointer is actual.
- * If <em>address</em> is not null, but <em>street</em> is null, the pointer is still actual.
+ * If both <em>address</em> and <em>street</em> are not null,
+ * the pointer is actual.
+ * If <em>address</em> is not null, but <em>street</em> is null,
+ * the pointer is still actual.
* If <em>address</em> is null, the pointer is not actual.
- * (In JavaBeans) if <em>address</em> is not a property of the root bean, a Pointer
- * for this path cannot be obtained at all - actual or otherwise.
+ * (In JavaBeans) if <em>address</em> is not a property of the root bean,
+ * a Pointer for this path cannot be obtained at all - actual or otherwise.
*/
public boolean isActual() {
if (index == WHOLE_COLLECTION) {
@@ -262,11 +285,11 @@
/**
* Returns the object the pointer points to; does not convert it
* to a "canonical" type.
- *
+ *
* @deprecated 1.1 Please use getNode()
*/
public Object getNodeValue(){
- return getNode();
+ return getNode();
}
/**
@@ -274,7 +297,7 @@
* to a "canonical" type.
*/
public abstract Object getNode();
-
+
/**
* Converts the value to the required type and changes the corresponding
* object to that value.
@@ -285,7 +308,8 @@
* Compares two child NodePointers and returns a positive number,
* zero or a positive number according to the order of the pointers.
*/
- public abstract int compareChildNodePointers(NodePointer pointer1, NodePointer pointer2);
+ public abstract int compareChildNodePointers(
+ NodePointer pointer1, NodePointer pointer2);
/**
* Checks if this Pointer matches the supplied NodeTest.
@@ -316,7 +340,7 @@
return testLocalName.equals(nodeName.getName());
}
else if (test instanceof NodeTypeTest) {
- if (((NodeTypeTest) test).getNodeType() == Compiler.NODE_TYPE_NODE) {
+ if (((NodeTypeTest) test).getNodeType() == Compiler.NODE_TYPE_NODE){
return isNode();
}
}
@@ -371,20 +395,31 @@
int index, Object value) {
throw new JXPathException(
"Cannot create an object for path "
- + asPath()
+ + asPath() + "/" + name + "[" + (index + 1) + "]"
+ ", operation is not allowed for this type of node");
}
/**
* Called by a child pointer when it needs to create a parent object
- * for a non-existent collection element. It may have to expand the collection,
- * then create an element object and return a new pointer describing the
- * newly created element.
+ * for a non-existent collection element. It may have to expand the
+ * collection, then create an element object and return a new pointer
+ * describing the newly created element.
*/
- public NodePointer createChild(JXPathContext context, QName name, int index) {
+ public NodePointer createChild(
+ JXPathContext context, QName name, int index) {
throw new JXPathException(
"Cannot create an object for path "
- + asPath()
+ + asPath() + "/" + name + "[" + (index + 1) + "]"
+ + ", operation is not allowed for this type of node");
+ }
+
+ /**
+ * Called to create a non-existing attribute
+ */
+ public NodePointer createAttribute(JXPathContext context, QName name){
+ throw new JXPathException(
+ "Cannot create an attribute for path "
+ + asPath() + "/@" + name
+ ", operation is not allowed for this type of node");
}
@@ -426,8 +461,8 @@
}
/**
- * Returns a NodeIterator that iterates over all attributes of the current node
- * matching the supplied node name (could have a wildcard).
+ * Returns a NodeIterator that iterates over all attributes of the current
+ * node matching the supplied node name (could have a wildcard).
* May return null if the object does not support the attributes.
*/
public NodeIterator attributeIterator(QName qname) {
@@ -449,7 +484,8 @@
/**
* Returns a NodePointer for the specified namespace. Will return null
- * if namespaces are not supported. Will return UNKNOWN_NAMESPACE if there is no such namespace.
+ * if namespaces are not supported.
+ * Will return UNKNOWN_NAMESPACE if there is no such namespace.
*/
public NodePointer namespacePointer(String namespace) {
return null;
@@ -520,20 +556,27 @@
StringBuffer buffer = new StringBuffer();
if (getParent() != null) {
buffer.append(getParent().asPath());
- // TBD: the following needs to be redesigned. What this condition says is
- // "if the parent of this node has already appended this node's name,
- // don't do it again". However, I would hate to add an ugly API like
- // "isResponsibleForAppendingChildName()".
- if (getParent().isNode() || (parent instanceof NullElementPointer)) {
+ // TBD: the following needs to be redesigned.
+ // What this condition says is
+ // "if the parent of this node has already appended this node's
+ // name, don't do it again". However, I would hate to add an ugly
+ // API like "isResponsibleForAppendingChildName()".
+ if (getParent().isNode() || (parent instanceof NullElementPointer)){
QName name = getName();
if (name != null) {
buffer.append('/');
+ if (attribute){
+ buffer.append('@');
+ }
buffer.append(name);
}
}
}
else {
QName name = getName();
+ if (attribute){
+ buffer.append('@');
+ }
buffer.append(name);
}
if (index != WHOLE_COLLECTION && isCollection()) {
@@ -542,9 +585,7 @@
return buffer.toString();
}
- public static int count = 0;
public Object clone() {
- count ++;
try {
NodePointer ptr = (NodePointer)super.clone();
if (parent != null){
@@ -564,7 +605,8 @@
}
public int compareTo(Object object){
- NodePointer pointer = (NodePointer) object; // Let it throw a ClassCastException
+ // Let it throw a ClassCastException
+ NodePointer pointer = (NodePointer) object;
if (parent == pointer.parent){
if (parent == null){
return 0;
@@ -588,9 +630,9 @@
return compareNodePointers(this, depth1, pointer, depth2);
}
- private int compareNodePointers(NodePointer p1, int depth1, NodePointer p2, int depth2){
-// System.err.println("Comparing " + p1.asPath() + " (" + depth1 + ") ~ " +
-// p2.asPath() + " (" + depth2 + ")");
+ private int compareNodePointers(
+ NodePointer p1, int depth1, NodePointer p2, int depth2)
+ {
if (depth1 < depth2){
int r = compareNodePointers(p1, depth1, p2.parent, depth2-1);
if (r != 0){
@@ -618,7 +660,8 @@
"Cannot compare pointers that do not belong to the same tree: '"
+ p1 + "' and '" + p2 + "'");
}
- int r = compareNodePointers(p1.parent, depth1 - 1, p2.parent, depth2 - 1);
+ int r = compareNodePointers(
+ p1.parent, depth1 - 1, p2.parent, depth2 - 1);
if (r != 0){
return r;
}
1.2 +32 -4 jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/model/jdom/JDOMNodePointer.java
Index: JDOMNodePointer.java
===================================================================
RCS file: /home/cvs/jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/model/jdom/JDOMNodePointer.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- JDOMNodePointer.java 26 Aug 2002 22:29:48 -0000 1.1
+++ JDOMNodePointer.java 13 Oct 2002 02:59:02 -0000 1.2
@@ -486,6 +486,34 @@
return ptr;
}
+ public NodePointer createAttribute(JXPathContext context, QName name){
+ if (!(node instanceof Element)){
+ return super.createAttribute(context, name);
+ }
+
+ Element element = (Element)node;
+ String prefix = name.getPrefix();
+ if (prefix != null){
+ Namespace ns = element.getNamespace(prefix);
+ if (ns == null){
+ throw new JXPathException("Unknown namespace prefix: " + prefix);
+ }
+ Attribute attr = element.getAttribute(name.getName(), ns);
+ if (attr == null){
+ element.setAttribute(name.getName(), "", ns);
+ }
+ }
+ else {
+ Attribute attr = element.getAttribute(name.getName());
+ if (attr == null){
+ element.setAttribute(name.getName(), "");
+ }
+ }
+ NodeIterator it = attributeIterator(name);
+ it.setPosition(1);
+ return it.getNodePointer();
+ }
+
public void remove(){
Element parent = nodeParent(node);
if (parent == null){
1.10 +27 -4 jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/model/dom/DOMNodePointer.java
Index: DOMNodePointer.java
===================================================================
RCS file: /home/cvs/jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/model/dom/DOMNodePointer.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- DOMNodePointer.java 26 Aug 2002 22:15:26 -0000 1.9
+++ DOMNodePointer.java 13 Oct 2002 02:59:02 -0000 1.10
@@ -403,6 +403,29 @@
return ptr;
}
+ public NodePointer createAttribute(JXPathContext context, QName name){
+ if (!(node instanceof Element)){
+ return super.createAttribute(context, name);
+ }
+ Element element = (Element)node;
+ String prefix = name.getPrefix();
+ if (prefix != null){
+ String ns = getNamespaceURI(prefix);
+ if (ns == null){
+ throw new JXPathException("Unknown namespace prefix: " + prefix);
+ }
+ element.setAttributeNS(ns, name.toString(), "");
+ }
+ else {
+ if (!element.hasAttribute(name.getName())){
+ element.setAttribute(name.getName(), "");
+ }
+ }
+ NodeIterator it = attributeIterator(name);
+ it.setPosition(1);
+ return it.getNodePointer();
+ }
+
public void remove(){
Node parent = node.getParentNode();
if (parent == null){
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>