如何在Java XPath查询中使用name()和/或node()?
我有一些XML大致如下所示:如何在Java XPath查询中使用name()和/或node()?,java,xml,xpath,Java,Xml,Xpath,我有一些XML大致如下所示: <project type="mankind"> <suggestion>Build the enterprise</suggestion> <suggestion>Learn Esperanto</suggestion> <problem>Solve world hunger</suggestion> <discussion>Do Vul
<project type="mankind">
<suggestion>Build the enterprise</suggestion>
<suggestion>Learn Esperanto</suggestion>
<problem>Solve world hunger</suggestion>
<discussion>Do Vulcans exist</discussion>
</project>
我的XPath是/project/*/name()
。我得到一个错误:
javax.xml.transform.TransformerException:未知节点类型:名称
类似于/project/suggestion
的查询按预期工作。我错过了什么?我想要一份标签名的清单
Java6(不要问)
我认为您的实现只支持XPath1.0。如果这是真的,那么只有以下几点可行:
"name(/project/*)"
原因是在XPath 1.0模型中,不能将函数(如name()
)用作路径表达式中的步骤。您的代码引发异常,在这种情况下,处理器会将您的函数name()
误认为未知节点测试(如comment()
)。但是使用路径表达式作为name()
函数的参数并没有错
不幸的是,如果一个XPath 1.0函数只能作为参数处理单个节点,则只会使用第一个节点序列。因此,结果很可能只得到第一个元素名
XPath 1.0的操作能力非常有限,通常解决此类问题的最简单方法是使用XPath作为查询语言的高级语言(在您的示例中是Java)。或者换句话说:用Java编写XPath表达式来检索所有相关节点并迭代结果,返回元素名
使用XPath2.0,您的初始查询就可以了。另请参见。下面的代码可能会回答您的原始问题
package com.example.xpath;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class XPathReader {
static XPath xPath = XPathFactory.newInstance().newXPath();
public static void main(String[] args) {
try {
FileInputStream file = new FileInputStream(new File("c:/mankind.xml"));
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = builderFactory.newDocumentBuilder();
Document xmlDocument = builder.parse(file);
XPathExpression expr = xPath.compile("//project/*");
NodeList list= (NodeList) expr.evaluate(xmlDocument, XPathConstants.NODESET);
for (int i = 0; i < list.getLength(); i++) {
Node node = list.item(i);
System.out.println(node.getNodeName() + "=" + node.getTextContent());
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (XPathExpressionException e) {
e.printStackTrace();
}
}
}
package com.example.xpath;
导入java.io.File;
导入java.io.FileInputStream;
导入java.io.FileNotFoundException;
导入java.io.IOException;
导入javax.xml.parsers.DocumentBuilder;
导入javax.xml.parsers.DocumentBuilderFactory;
导入javax.xml.parsers.parserConfiguration异常;
导入javax.xml.xpath.xpath;
导入javax.xml.xpath.XPathConstants;
导入javax.xml.xpath.XPathExpression;
导入javax.xml.xpath.XPathExpressionException;
导入javax.xml.xpath.XPathFactory;
导入org.w3c.dom.Document;
导入org.w3c.dom.Node;
导入org.w3c.dom.NodeList;
导入org.xml.sax.SAXException;
公共类XPathReader{
静态XPath=XPathFactory.newInstance().newXPath();
公共静态void main(字符串[]args){
试一试{
FileInputStream文件=新的FileInputStream(新文件(“c:/humany.xml”);
DocumentBuilderFactory builderFactory=DocumentBuilderFactory.newInstance();
DocumentBuilder=builderFactory.newDocumentBuilder();
Document xmlDocument=builder.parse(文件);
XPathExpression expr=xPath.compile(“//project/*”);
NodeList list=(NodeList)expr.evaluate(xmlDocument,XPathConstants.NODESET);
对于(int i=0;i
假设输入已纠正(解决世界饥饿问题),代码应打印:
建议=建立企业建议=学习世界语
问题=解决世界饥饿问题
discussion=Vulcans是否存在您使用的是什么版本的XPath?您应该使用/project/@name而不是/project/*/name()@aoulhent操作试图检索
/project/*
的元素名,而不是此属性的内容。@MathiasMüller Java6(不要问)。和thx用于澄清。是的,我不需要顶层的属性,但需要元素。我将更新这个问题以更好地消除潜在的混淆,现在我得到一个org.apache.xpath.XPathException:cannotconvert#STRING to NodeList!,但我想那是因为我的XPathConstants.NODESET。当我尝试使用XPathConstants.STRING时,它可以工作。现在。。。。有没有办法确定返回的是字符串还是节点集。如果我省略了参数,它总是一个字符串back@stwissel我不熟悉Java Transformer,但是计算路径表达式的方法是否必须返回节点列表
?你能写不同的方法吗,一个用于查找节点,另一个用于查找字符串?这是计划B。当然,我必须猜测哪个XPath表达式(我从配置文件中读取它们)将返回字符串,哪个XPath表达式将返回节点集(或者我只是尝试捕捉错误)。@stwissel如我所说,尽管我很想帮助Java,那不完全是我的专长。我发现提前确定退货类型很麻烦,我相信有更好的方法。让一个方法来计算XPath,只编写计算到节点集的表达式,返回节点并将它们传递给另一个方法,该方法将一组元素作为参数并返回它们的名称,怎么样?我不会编写XPath,因此我没有控制权。我希望90%是节点集,所以我将在其周围放置一个错误处理程序,如果失败,请使用文本重试。不性感,但是XML不是很大,所以我们讨论毫秒延迟。Thx用于具有语法的指针。感谢swift replyThx提供的代码。这里的挑战是:XPath返回整个元素,而不仅仅是名称。我需要能够区分基于XPath获取元素的名称还是内容。用一个
package com.example.xpath;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class XPathReader {
static XPath xPath = XPathFactory.newInstance().newXPath();
public static void main(String[] args) {
try {
FileInputStream file = new FileInputStream(new File("c:/mankind.xml"));
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = builderFactory.newDocumentBuilder();
Document xmlDocument = builder.parse(file);
XPathExpression expr = xPath.compile("//project/*");
NodeList list= (NodeList) expr.evaluate(xmlDocument, XPathConstants.NODESET);
for (int i = 0; i < list.getLength(); i++) {
Node node = list.item(i);
System.out.println(node.getNodeName() + "=" + node.getTextContent());
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (XPathExpressionException e) {
e.printStackTrace();
}
}
}