我们正在使用 dom4j 1.6.1 来解析来自某处的 XML。有时,应答器会提到 namespace (例如:),有时不会()。它调用 Element.selectSingleNode(String s ) 失败。
目前我们有 3 个解决方案,但我们对它们并不满意
1 - 在对 xml 文档执行任何操作之前删除所有出现的命名空间
xml = xml .replaceAll("xmlns=\"[^\"]*\"","");
xml = xml .replaceAll("ds:","");
xml = xml .replaceAll("etm:","");
[...] // and so on for each kind of namespace
2 - 在获取节点之前删除命名空间 通过调用
Element.remove(Namespace ns)
但它只适用于一个节点和第一级 child
3 - 通过
打乱代码node = rootElement.selectSingleNode(NameWithoutNameSpace)
if ( node == null )
node = rootElement.selectSingleNode(NameWithNameSpace)
那么……你怎么看?女巫一号不是更糟吗?您有其他解决方案要提出吗?
最佳答案
我想删除任何 namespace 信息(声明和标记)以简化 xpath 评估。我最终得到了这个解决方案:
String xml = ...
SAXReader reader = new SAXReader();
Document document = reader.read(new ByteArrayInputStream(xml.getBytes()));
document.accept(new NameSpaceCleaner());
return document.asXML();
其中 NameSpaceCleaner 是 dom4j 访问者:
private static final class NameSpaceCleaner extends VisitorSupport {
public void visit(Document document) {
((DefaultElement) document.getRootElement())
.setNamespace(Namespace.NO_NAMESPACE);
document.getRootElement().additionalNamespaces().clear();
}
public void visit(Namespace namespace) {
namespace.detach();
}
public void visit(Attribute node) {
if (node.toString().contains("xmlns")
|| node.toString().contains("xsi:")) {
node.detach();
}
}
public void visit(Element node) {
if (node instanceof DefaultElement) {
((DefaultElement) node).setNamespace(Namespace.NO_NAMESPACE);
}
}
}
关于java - 使用 dom4j 清理命名空间处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1422395/