我正在研究用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();
}
Huum其實事情是,我可能不應該添加XSL腳本是混合的事情解決了。假設我使用這個在線測試器: http://www.freeformatter.com/xpath-tester.html 我把我的XML和下面的xPath表達式:// namespace :: * 它給了我一些結果。我的問題是,我沒有設法在Java中使用該表達式。 – user930394
你可以發佈整個類來測試提取xml元素屬性嗎? 我想你必須得到那個單一節點的屬性。 jaxb對此有很好的支持。如果你把可運行的代碼,我可以試試看 – BRjava