最近在做esb项目的时候,有位同事使用dom4j去删除一段xml的一个org.dom4j.Element的namespace。是这样写的:
Element element = document.getRootElement();
Namespace namespace = new Namespace(prefix, uri);
element.remove(namespace);
这段代码很简单,就是删除一个namespace,可是就是删除不掉,那个remove方法有一个返回值,如果删除失败就会返回false,经过调试返回值一直是false。可是那个element确实有那么一个namespace,从这个element对象中可以获取里面的namespace对象,也能看到它的prefix和uri,确实没错!
其实dom4j内部也是使用的一个ArrayList,于是作了这么一个实验:
public class TestRemove {
public static void main(String[] args) {
List<User> list = new ArrayList<User>();
list.add(new User("heyao",1));
list.add(new User("hefei",2));
boolean flag = list.remove(new User("heyao",1));
int i = list.size();
}
}
class User {
private String name ;
private int id;
public User(String name,int id) {
this.setName(name);
this.setId(id);
}
//省略setter getter
}
很明显,这样删除元素是不对的,这里的flag肯定也是false,于是我们再看一下ArrayList的实现:
public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
}
注意,它是用的object的equals方法,所以,如果对象不是Java的原生对象的话,它比较的应该是内存地址。这也是我们在写一个对象时要重写equals方法的原因。
于是要删除那个namespace必须去查找到那个namespace对象,然后直接删除这个对象才能起作用。
有三个方法可以用:
element.getNamespace();
element.getNamespaceForPrefix(arg0)
element.getNamespaceForURI(arg0)