2010-04-09 63 views
4

我需要處理XML DOM,最好使用JDOM,我可以在節點上執行XPath搜索。我知道節點名稱或路徑,但我想忽略命名空間完全,因爲有時文檔帶有命名空間,有時沒有,並且我不能依賴特定的值。那可能嗎?怎麼樣?如何讓JDOM/XPath忽略名稱空間?

+0

與其忽略它們,您也可以檢索並使用它們。請參閱[如何使用Xpath檢索XML文件中的名稱空間](http://stackoverflow.com/q/122463/507761) – 2012-03-13 21:50:44

回答

3

我知道這個問題有點老了,但對於那些稍後查看的人,您可以重寫一些JDOM默認類來有效地忽略命名空間。您可以將自己的JDOMFactory實現傳遞給SAXBuilder,該SAXBuilder會忽略傳入它的所有名稱空間值。

然後覆蓋SAXBuilder類並實現createContentHandler方法,以便它返回一個SAXHandler,其中包含startPrefixMapping方法的空白定義。

我沒有在生產設置中使用這個警告emptor,但我已經驗證它可以處理一些我已經完成的快速和骯髒的XML事情。

16
/ns:foo/ns:bar/@baz 

成爲

/*[local-name() = 'foo']/*[local-name() = 'bar']/@baz 

你明白了吧。不要指望它也快如閃電。

+0

我嘗試了以下解決方案:http://stackoverflow.com/questions/543049/default-xml -namespace-jdom-and-xpath 只要根元素聲明瞭任何名稱空間,它就簡單多了。但是如果沒有命名空間,它不會 - 所以我使用上面的,或者我有一個單獨的解決方案沒有名稱空間。 – AdSR 2010-04-09 14:36:34

+0

@AdSR:您的問題似乎意味着您不知道輸入文檔的名稱空間狀態,它們隨機出現。在這種情況下,以上是「最安全的」,如下所示:它將始終有效,但是您失去了在'x:foo'和'ns:foo'之間區別的能力。 – Tomalak 2010-04-09 15:25:34

+0

謝謝,這個解決方案在jdom 1.x中爲我工作(/ *:foo沒有工作)。上面的 – expert 2012-08-29 16:42:02

3

您可以使用/*:foo(XPath 2.0或更高版本)或/yournamespace:*as explained here

第一個變體選擇具有匹配名稱的所有節點,而不管它們屬於哪個名稱空間,包括沒有名稱空間。後者選擇屬於特定名稱空間的所有節點,而不管節點名稱如何。

+0

@ user520567:您的第二個QName測試('NS:*')是有效的XPath 1.0/2.0,但第一個('*:Name')只是有效的XPath 2.0。沒有這些信息,你的答案價值就會降低...... – 2010-11-25 21:53:32

+0

它被命名爲xpath2-intro;) 實際上,問題僅由第一個表達式回答。但是我確定我應該寫這個。 – akostadinov 2010-12-02 07:23:23

2

這是一個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; 
    } 

}