欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

你这样remove过吗

程序员文章站 2022-07-14 16:56:50
...
最近在做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)
相关标签: XML