如何让JDOM/XPath忽略名称空间?
我需要处理XML DOM,最好使用JDOM,我可以在节点上执行XPath搜索。我知道节点名称或路径,但我想忽略命名空间完全,因为有时文档带有命名空间,有时没有,并且我不能依赖特定的值。那可能吗?怎么样?如何让JDOM/XPath忽略名称空间?
我知道这个问题有点老了,但对于那些稍后查看的人,您可以重写一些JDOM默认类来有效地忽略命名空间。您可以将自己的JDOMFactory实现传递给SAXBuilder,该SAXBuilder会忽略传入它的所有名称空间值。
然后覆盖SAXBuilder类并实现createContentHandler方法,以便它返回一个SAXHandler,其中包含startPrefixMapping方法的空白定义。
我没有在生产设置中使用这个警告emptor,但我已经验证它可以处理一些我已经完成的快速和肮脏的XML事情。
/ns:foo/ns:bar/@baz
成为
/*[local-name() = 'foo']/*[local-name() = 'bar']/@baz
你明白了吧。不要指望它也快如闪电。
我尝试了以下解决方案:http://stackoverflow.com/questions/543049/default-xml -namespace-jdom-and-xpath 只要根元素声明了任何名称空间,它就简单多了。但是如果没有命名空间,它不会 - 所以我使用上面的,或者我有一个单独的解决方案没有名称空间。 – AdSR 2010-04-09 14:36:34
@AdSR:您的问题似乎意味着您不知道输入文档的名称空间状态,它们随机出现。在这种情况下,以上是“最安全的”,如下所示:它将始终有效,但是您失去了在'x:foo'和'ns:foo'之间区别的能力。 – Tomalak 2010-04-09 15:25:34
谢谢,这个解决方案在jdom 1.x中为我工作(/ *:foo没有工作)。上面的 – expert 2012-08-29 16:42:02
您可以使用/*:foo
(XPath 2.0或更高版本)或/yournamespace:*
as explained here。
第一个变体选择具有匹配名称的所有节点,而不管它们属于哪个名称空间,包括没有名称空间。后者选择属于特定名称空间的所有节点,而不管节点名称如何。
@ user520567:您的第二个QName测试('NS:*')是有效的XPath 1.0/2.0,但第一个('*:Name')只是有效的XPath 2.0。没有这些信息,你的答案价值就会降低...... – 2010-11-25 21:53:32
它被命名为xpath2-intro;) 实际上,问题仅由第一个表达式回答。但是我确定我应该写这个。 – akostadinov 2010-12-02 07:23:23
这是一个jDOM2解决方案,有在一年的生产环境中运行没有问题。
public class JdomHelper {
private static final SAXHandlerFactory FACTORY = new SAXHandlerFactory() {
@Override
public SAXHandler createSAXHandler(JDOMFactory factory) {
return new SAXHandler() {
@Override
public void startElement(
String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
super.startElement("", localName, qName, atts);
}
@Override
public void startPrefixMapping(String prefix, String uri) throws SAXException {
return;
}
};
}
};
/** Get a {@code SAXBuilder} that ignores namespaces.
* Any namespaces present in the xml input to this builder will be omitted from the resulting {@code Document}. */
public static SAXBuilder getSAXBuilder() {
// Note: SAXBuilder is NOT thread-safe, so we instantiate a new one for every call.
SAXBuilder saxBuilder = new SAXBuilder();
saxBuilder.setSAXHandlerFactory(FACTORY);
return saxBuilder;
}
}
与其忽略它们,您也可以检索并使用它们。请参阅[如何使用Xpath检索XML文件中的名称空间](http://stackoverflow.com/q/122463/507761) – 2012-03-13 21:50:44