Java XPath从多个节点获取文本
我需要从以下位置创建一个名为text的StringArray:Java XPath从多个节点获取文本,java,xml,xpath,jaxp,Java,Xml,Xpath,Jaxp,我需要从以下位置创建一个名为text的StringArray: 我如何查询“xyz”、“bla”和更多这些 可能是您见过的最糟糕的代码,但无论如何: NodeList result1 = (NodeList) xPath.evaluate("//@name", example, XPathConstants.NODESET); for(int i=0; i<result1.getLength();i++) { System.out.println("read 1:" +resu
我如何查询“xyz”、“bla”和更多这些
可能是您见过的最糟糕的代码,但无论如何:
NodeList result1 = (NodeList) xPath.evaluate("//@name", example, XPathConstants.NODESET);
for(int i=0; i<result1.getLength();i++) {
System.out.println("read 1:" +result1.item(i));
}
//console output is:
//read 1:name="xyz"
//read 1:name="bla"
ArrayList<String> liste;
liste = new ArrayList<String>(result1.getLength());
for (int i=0; i<result1.getLength();i++){
String read=xPath.evaluate("//@name", example);
liste.add(read);
System.out.println("read 2: "+read);
}
System.out.println("complete list: " +liste);
//console output is:
//read 2:name="xyz"
//read 2:name="xyz"
//complete list: [xyz, xyz]
nodelistresult1=(NodeList)xPath.evaluate(“/@name”,例如xpathcontents.NODESET);
对于(int i=0;i来说,您似乎成功地检索了结果列表,但随后在每次迭代中循环这些结果并重新计算XPath。在您第一次循环result1时,这些值似乎已正确打印出来,因此,为什么不替换此值:
String read=xPath.evaluate("//@name", example);
为此:
String read = result1.item(i).toString();
导入静态javax.xml.xpath.XPathConstants.NODESET;
导入静态org.apache.commons.lang3.StringUtils.firstNoneEmpty;
导入静态org.apache.commons.lang3.StringUtils.trim;
/**
*返回第一个非空结果
*
*@param xpaths
*@返回第一个非空结果,如果未找到结果,则返回null
*/
公共静态字符串xpathValue(文档、字符串…xpaths){
列表结果=XPathValue(文档,xpaths);
if(result.isEmpty())
返回null;
if(result.size()==1)
返回结果get(0);
抛出新的IllegalStateException(格式(“非唯一结果:%s”,结果));
}
/**
*返回第一个非空结果
*
*@param xpaths
*@如果未找到结果,则返回第一个非空结果或空列表
*/
公共静态列表XPathValue(文档、字符串…xpaths){
XPathFactory f=XPathFactory.newInstance();
返回流(XPath)
.map(xpath->evaluateXpath(文档,f,xpath))
.filter(CollectionUtils::isNotEmpty)
.findFirst().orElse(emptyList());
}
私有静态列表路径(文档文档、XPathFactory f、字符串xpath){
试一试{
NodeList result=(NodeList)f.newXPath().evaluate(xpath,document,NODESET);
List liste=newarraylist(result.getLength());
for(int i=0;i
我试过了,但它只提供了第一项。例如,上面的示例中,它只会编写XYZ。代码在哪里?选择单个节点和多个节点可能有不同的方法,您使用的是前者。根据您使用的内容,您可能会在结果集上循环。
String read = result1.item(i).toString();
import static javax.xml.xpath.XPathConstants.NODESET;
import static org.apache.commons.lang3.StringUtils.firstNonEmpty;
import static org.apache.commons.lang3.StringUtils.trim;
/**
* Returns first non-empty result
*
* @param xpaths
* @return first non-empty result or null if result not found
*/
public static String xpathValue(Document document, String... xpaths) {
List<String> result = xpathValues(document, xpaths);
if (result.isEmpty())
return null;
if (result.size() == 1)
return result.get(0);
throw new IllegalStateException(format("Non-unique result: %s", result));
}
/**
* Returns first non-empty result
*
* @param xpaths
* @return first non-empty result or empty list if result not found
*/
public static List<String> xpathValues(Document document, String... xpaths) {
XPathFactory f = XPathFactory.newInstance();
return stream(xpaths)
.map(xpath -> evaluateXpath(document, f, xpath))
.filter(CollectionUtils::isNotEmpty)
.findFirst().orElse(emptyList());
}
private static List<String> evaluateXpath(Document document, XPathFactory f, String xpath) {
try {
NodeList result = (NodeList) f.newXPath().evaluate(xpath, document, NODESET);
List<String> liste = new ArrayList<String>(result.getLength());
for (int i = 0; i < result.getLength(); i++) {
Node item = result.item(i);
liste.add(firstNonEmpty(trim(item.getTextContent()), item.getNodeValue()));
}
return liste;
} catch (XPathExpressionException e) {
throw new IllegalArgumentException("Cannot evaluate xpath: " + xpath, e);
}
}