Java XPath从多个节点获取文本

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

我需要从以下位置创建一个名为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:" +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);
    }
}