简体   繁体   中英

Xpath in Java - return search result tag position

I want to search for a text value in a XML file and return the position of each search result.

Asuming i have this xml file:

<tag>
    <tag>
        <tag>333</tag>
    </tag>

    <tag>
        <tag>
            <tag>333</tag>
       </tag>
   </tag>
</tag>

I would be searching for the value "333":

String expression = "//tag[text()=333]/ancestor::*";
NodeList email = (NodeList) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODESET);
String resultString = "";
for(int i=0; i< email.getLength();i++){

        Element labTest = (Element) email.item(i);
        resultString  += labTest.toString().replace("[tag: null]","tag[0]") + " ";
    }

What i want it to return is 2 nodes each containing the position of the element. Searching for 333 the output would be:

tag[0] tag[0]
tag[0] tag[0] tag[0] 

At the moment the search returns:

tag[0] tag[0] tag[0] tag[0]

How can i achieve this? Should i aproach the problem differently?

A XPath node-set is a collection without duplicates, so your code does not what you intended. Therefore

  1. select "//tag[text()=333]/
  2. for each of these nodes select ancestor::* and create your output string from this result-set.
  1. Ancestors won't be selected twice. So the root <tag> will only be selected once.

  2. Each iteration selects one of the ancestor tags; a line separator won't be added auto-magically.

  3. To gain insight, add a level attribute to the tags ( <tag l='0'> , add one for each level deeper), and output the level. Suppose you start at 0 for the root, and you output levels you will see the output as 0112 .


For sports, I made the following snippet. The first output will show the output order of the levels selected. The second will output what you require in your question.

import java.io.StringReader;
import javax.xml.xpath.*;
import org.w3c.dom.*;
import org.xml.sax.InputSource;

public class XPathTags {
    private static String xml1=
"<tag l='0'>"+
"    <tag l='1'>"+
"        <tag l='2'>333</tag>"+
"    </tag>"+
"    <tag l='1'>"+
"        <tag l='2'>"+
"            <tag l='3'>333</tag>"+
"       </tag>"+
"   </tag>"+
"</tag>";

    private static String xml2=
"<tag>"+
"    <tag>"+
"        <tag>333</tag>"+
"    </tag>"+
"    <tag>"+
"        <tag>"+
"            <tag>333</tag>"+
"       </tag>"+
"   </tag>"+
"</tag>";

    private static String xpathExpr1=
"//tag[text()=333]/ancestor::*/@l";
    private static String xpathExpr2=
"//tag[text()=333]";

    public static void main(String[] args) {
        try {
            XPath xpath = XPathFactory.newInstance().newXPath();
            XPathExpression expr = xpath.compile(xpathExpr1);
            NodeList nodeList = (NodeList) expr.evaluate(new InputSource(new StringReader(xml1)),XPathConstants.NODESET);
            String resultString = "";
            for( int i = 0; i != nodeList.getLength(); ++i ) {
                resultString += nodeList.item(i).getNodeValue();
            }
            System.out.println(resultString);

            resultString = "";
            expr = xpath.compile(xpathExpr2);
            XPathExpression anc = xpath.compile("ancestor::*");
            nodeList = (NodeList) expr.evaluate(new InputSource(new StringReader(xml2)),XPathConstants.NODESET);
            for( int i = 0; i != nodeList.getLength(); ++i ) {
                Node n = (Node) nodeList.item( i );
                NodeList ancestors = (NodeList) anc.evaluate(n,XPathConstants.NODESET);
                for( int j = 0; j != ancestors.getLength(); ++j )
                    resultString += ancestors.item(j).toString().replace("[tag: null]", "tag[0]");
                resultString += System.lineSeparator();
            }
            System.out.println(resultString);

        } catch (XPathExpressionException e) {
            e.printStackTrace();
        }
    }
}

Output:

0112
tag[0]tag[0]
tag[0]tag[0]tag[0]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM