简体   繁体   中英

Get nodes with xPath in Java

I need to get the value 28.42 only if description is T1 and for each value of job description (Mecánica, Guarnecidos,...) from the list with xPath.

<priceByHourList>
<priceByHour locked="false">
    <value>
        <job>
            <jobId>4</jobId>
            <description>
                <id>4</id>
                <value>Mecánica</value>
            </description>
        </job>
        <technician>
            <technicianId>1</technicianId>
            <description>T1</description>
        </technician>
        <value>28.42</value>
    </value>
</priceByHour>
<priceByHour locked="false">
    <value>
        <job>
            <jobId>4</jobId>
            <description>
                <id>4</id>
                <value>Mecánica</value>
            </description>
        </job>
        <technician>
            <technicianId>2</technicianId>
            <description>T2</description>
        </technician>
        <value>28.42</value>
    </value>
</priceByHour>
<priceByHour locked="false">
    <value>
        <job>
            <jobId>4</jobId>
            <description>
                <id>4</id>
                <value>Mecánica</value>
            </description>
        </job>
        <technician>
            <technicianId>3</technicianId>
            <description>T3</description>
        </technician>
        <value>28.42</value>
    </value>
</priceByHour>
<priceByHour locked="false">
    <value>
        <job>
            <jobId>1</jobId>
            <description>
                <id>1</id>
                <value>Electricidad</value>
            </description>
        </job>
        <technician>
            <technicianId>2</technicianId>
            <description>T2</description>
        </technician>
        <value>28.42</value>
    </value>
</priceByHour>
<priceByHour locked="false">
    <value>
        <job>
            <jobId>1</jobId>
            <description>
                <id>1</id>
                <value>Electricidad</value>
            </description>
        </job>
        <technician>
            <technicianId>3</technicianId>
            <description>T3</description>
        </technician>
        <value>28.42</value>
    </value>
</priceByHour>
<priceByHour locked="false">
    <value>
        <job>
            <jobId>5</jobId>
            <description>
                <id>5</id>
                <value>Guarnecidos</value>
            </description>
        </job>
        <technician>
            <technicianId>1</technicianId>
            <description>T1</description>
        </technician>
        <value>28.42</value>
    </value>
</priceByHour>

And I'm trying to get the list but the node is the same.

     for (int i = 0; i < nodes.getLength(); i++) {
            Element pieza = (Element) nodes.item(i);            
            System.out.println(pieza.getNodeName());}

Because you need two details : job/description and value you need two xpath expressions. You can do something like below :

public class PriceByHour
{

    private static class PriceDetails
    {
        String jobDesc;
        String value;
    }

    public static void main( String... args )
    {
        try
        {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();

            Document doc = db.parse( new File( ".//pricebyhour.xml" ) );
            XPathFactory xPathFactory = XPathFactory.newInstance();
            XPath xpath = xPathFactory.newXPath();

            List<PriceDetails> priceDetailsList = new ArrayList<PriceDetails>();

            XPathExpression jobExpr = xpath.compile( "//priceByHour/value[technician[./description='T1']]/job/description/value" );
            XPathExpression valueExpr = xpath.compile( "//priceByHour/value[technician[./description='T1']]/value" );

            Object exprEval = jobExpr.evaluate( doc, XPathConstants.NODESET );
            NodeList jobNodes = null;
            NodeList valueNodes  = null;
            if ( exprEval != null && exprEval instanceof NodeList )
            {
                jobNodes = (NodeList)exprEval;
            }

            exprEval = valueExpr.evaluate( doc, XPathConstants.NODESET );
            if ( exprEval != null && exprEval instanceof NodeList )
            {
                valueNodes = (NodeList)exprEval;
            }

            if ( jobNodes != null && valueNodes != null && jobNodes.getLength() == valueNodes.getLength() )
            {
                for ( int i = 0 ; i < jobNodes.getLength(); i++ )
                {
                    Node jobNode = jobNodes.item( i );
                    Node valueNode = valueNodes.item( i );
                    PriceDetails priceDetails = new PriceDetails();
                    priceDetails.jobDesc = jobNode.getTextContent();
                    priceDetails.value = valueNode.getTextContent();
                    priceDetailsList.add( priceDetails );

                }
            }

            for ( PriceDetails priceDetails : priceDetailsList )
            {
                System.out.println( "Job description is : " + priceDetails.jobDesc + ", " + "Value is : " + priceDetails.value );
            }

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

    }
}

Place your xml in a file called pricebyhour.xml and run this code.

Notice that first xpath fetches job description and second xpath fetches value. The number of job descriptions and values should match, and you can actually build a class that holds two values job description and value, as shown by class PriceDetails .

Output is :

Job description is : Mecánica, Value is : 28.42
Job description is : Guarnecidos, Value is : 28.42

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