你这样remove过吗

最近在做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)