2014-01-16 77 views
0

我正在研究用Java編寫的解析器。我可以接收來自各個位置的XML提要,並提供各種內容。我需要從提要中提取所有名稱空間,根據提要調用這個或那個。我在Java中獲得這個問題時遇到了一些麻煩,我不確定問題出在哪裏。Xpath - Java - 從XML中提取多個名稱空間

讓我們考慮這個XML:

<?xml version="1.0"?> 
     <?xml-stylesheet type='text/xsl' href='new.xsl'?> 
<test xmlns:mynsone="http://www.ns.com/test" xmlns:demons="http://www.demons.com/test"> 
    <p xmlns:domain="http://www.toto.com/test"> 
     this is a test. 
    </p> 
</test> 

爲了測試我的XPath表達式(我是比較新的話),我寫了應用於XML一點的.xsl腳本:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output 
      method="html" 
      encoding="ISO-8859-1" 
      doctype-public="-//W3C//DTD XHTML//EN" 
      doctype-system="http://www.w3.org/TR/2001/REC-xhtml11-20010531" 
      indent="yes" /> 
    <xsl:template match="/"> 
     <xsl:for-each select="//namespace::*"> 
      <xsl:value-of select="." /> 
      <xsl:text> </xsl:text><br /> 
     </xsl:for-each> 
    </xsl:template> 
</xsl:stylesheet> 

這提供了正確的命名空間我遇到迭代節點列表:

http://www.w3.org/XML/1998/namespace 
http://www.demons.com/test 
http://www.ns.com/test 
http://www.w3.org/XML/1998/namespace 
http://www.demons.com/test 
http://www.ns.com/test 
http://www.toto.com/test 

現在我GE回到Java:這裏是我使用的代碼。

InputStream file = url.openStream(); 
    DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); 
    DocumentBuilder builder = builderFactory.newDocumentBuilder(); 
    org.w3c.dom.Document xmlDocument = builder.parse(file); 

    XPath xPath = XPathFactory.newInstance().newXPath(); 
    String expression = "//namespace::*"; 
    System.out.println(expression); 

    NodeList nodelist = (NodeList) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODESET); 

    for (int k = 0; k < nodelist.getLength(); k++) 
    { 
     Node mynode = nodelist.item(k); 
     System.out.println(mynode.toString()); 
    } 

這裏是結果,我獲得:

xmlns:mynsone="http://www.ns.com/test" 
org.ap[email protected]7dbb8ca4 
xmlns:domain="http://www.toto.com/test" 

因此,不返回的 「惡魔」 的命名空間。問題是,如果我在1個節點上放置了幾個名稱空間,則只有1個是以Java返回的,而在XSL腳本上則全部顯示。

我希望自己明確自己;我花了過去的日子在網頁瀏覽的例子,我不知道如果我真的很接近,但只是失去了一點點或如果我的表情根本不合適..

在此先感謝。

行,所以我最終使用的XPath 2.0做到這一點,利用撒克遜-HE 9.4:

public static boolean detectGeoRssNamespace(InputStream sourceFeed) { 
    try { 
     if (sourceFeed.markSupported()) { 
      sourceFeed.reset(); 
     } 

     String objectModel = NamespaceConstant.OBJECT_MODEL_SAXON; 
     System.setProperty("javax.xml.xpath.XPathFactory:"+NamespaceConstant.OBJECT_MODEL_SAXON, "net.sf.saxon.xpath.XPathFactoryImpl"); 
     XPathFactory xpathFactory = XPathFactory.newInstance(objectModel); 
     XPath xpath = xpathFactory.newXPath(); 

     InputSource is = new InputSource(sourceFeed); 
     SAXSource ss = new SAXSource(is); 
     NodeInfo doc = ((XPathEvaluator)xpath).setSource(ss);  

     String xpathExpressionStr = "distinct-values(//*[name()!=local-name()]/ concat('prefix=', substring-before(name(), ':'), '&uri=', namespace-uri()))"; 
     XPathExpression xpathExpression = xpath.compile(xpathExpressionStr); 

     List nodelist = (List)xpathExpression.evaluate(doc, XPathConstants.NODESET); 

     System.out.println("<output>"); 
     Iterator iter = nodelist.iterator(); 
     while (iter.hasNext()) { 
      Object line = (Object)iter.next(); 
      System.out.println(line.toString()); 
     } 
     System.out.println("</output>"); 

    } catch (XPathFactoryConfigurationException e) { 
     e.printStackTrace(); 
    } catch (XPathException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (Exception e) { 
     e.printStackTrace();     

    } 

回答

0

問題是使用XPath 2.0(包含代碼有問題)

0

如果你提取此命名空間不同的XML元素。

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output 
      method="html" 
      encoding="ISO-8859-1" 
      doctype-public="-//W3C//DTD XHTML//EN" 
      doctype-system="http://www.w3.org/TR/2001/REC-xhtml11-20010531" 
      indent="yes" /> 
    <xsl:template match="/"> 
     <xsl:for-each select="//namespace::*"> 
      <namespace> 
      <xsl:value-of select="." /> 
      </namespace> 
      <xsl:text> </xsl:text><br /> 
     </xsl:for-each> 
    </xsl:template> 
</xsl:stylesheet> 
+0

Huum其實事情是,我可能不應該添加XSL腳本是混合的事情解決了。假設我使用這個在線測試器: http://www.freeformatter.com/xpath-tester.html 我把我的XML和下面的xPath表達式:// namespace :: * 它給了我一些結果。我的問題是,我沒有設法在Java中使用該表達式。 – user930394

+0

你可以發佈整個類來測試提取xml元素屬性嗎? 我想你必須得到那個單一節點的屬性。 jaxb對此有很好的支持。如果你把可運行的代碼,我可以試試看 – BRjava