javaxmldomxpathdom4j

XPath to select multiple child values


How can i select all/multiple the values which satify below condition

XPATH

/X/X1/X2[@code='b']/X3/value

XML:

<X>
    <X1>
        <X2 code="a">
            <X3>
                <value>x3a1</value>
            </X3>
        </X2>
    </X1>
    <X1>
        <X2 code="b">
            <X3>
                <value>x3b11</value>
            </X3>
        </X2>
    </X1>
    <X1>
        <X2 code="b">
            <X3>
                <value>X3b12</value>
            </X3>
        </X2>
    </X1>

</X>

Code:

import org.dom4j.Document;
import org.dom4j.Node;
Document doc = reader.read(new StringReader(xml));
Node valueNode = doc.selectSingleNode(XPATH);

Expected value

x3b11, X3b12

Solution

  • Instead of Document.selectSingleNode(), use Document.selectNodes() to select multiple nodes.

    Also consider XPath.selectNodes(); here is a full example from the DOM4J Cookbook:

    import java.util.Iterator;
    
    import org.dom4j.Documet;
    import org.dom4j.DocumentHelper;
    import org.dom4j.Element;
    import org.dom4j.XPath;
    
    public class DeployFileLoaderSample {
    
      private org.dom4j.Document doc;
      private org.dom4j.Element root;
    
      public void browseRootChildren() {
    
        /* 
          Let's look how many "James" are in our XML Document an iterate them  
          ( Yes, there are three James in this project ;) )
        */
          
        XPath xpathSelector = DocumentHelper.createXPath("/people/person[@name='James']");
        List results = xpathSelector.selectNodes(doc);
        for ( Iterator iter = results.iterator(); iter.hasNext(); ) {
          Element element = (Element) iter.next();
          System.out.println(element.getName());
        }
    
        // select all children of address element having person element with attribute and value "Toby" as parent
        String address = doc.valueOf( "//person[@name='Toby']/address" );
    
        // Bob's hobby
        String hobby = doc.valueOf( "//person[@name='Bob']/hobby/@name" );
    
        // the second person living in UK
        String name = doc.value( "/people[@country='UK']/person[2]" );
        
        // select people elements which have location attriute with the value "London"
        Number count = doc.numberValueOf( "//people[@location='London']" );
      }
    }