Locating Information with XPath


If you want to locate a specific piece of information in an XML document, then it can be a bit of a hassle to navigate the nodes of the DOM tree. The XPath language makes it simple to access tree nodes. For example, suppose you have this XML document:

 <configuration>    . . .    <database>       <username>dbuser</username>       <password>secret</password>       . . .    </database> </configuration> 

You can get the database user name by evaluating the XPath expression

 /configuration/database/username 

That's a lot simpler than the plain DOM approach:

  1. Get the document node.

  2. Enumerate its children.

  3. Locate the database element.

  4. Get its first child, the username element.

  5. Get its first child, a Text node.

  6. Get its data.

An XPath can describe a set of nodes in an XML document. For example, the XPath

 /gridbag/row 

describes the set of all row elements that are children of the gridbag root element. You can select a particular element with the [] operator:

 /gridbag/row[1] 

is the first row. (The index values start at 1.)

Use the @ operator to get attribute values. The XPath expression

 /gridbag/row[1]/cell[1]/@anchor 

describes the anchor attribute of the first cell in the first row. The XPath expression

 /gridbag/row/cell/@anchor 

describes all anchor attribute nodes of cell elements within row elements that are children of the gridbag root node.

There are a number of useful XPath functions. For example,

 count(/gridbag/row) 

returns the number of row children of the gridbag root. There are many more elaborate XPath expressionssee the specification at http://www.w3c.org/TR/xpath or the nifty online tutorial at http://www.zvon.org/xxl/XPathTutorial/General/examples.html.

JDK 5.0 adds an API to evaluate XPath expressions. You first create an XPath object from an XPathFactory:

 XPathFactory xpfactory = XPathFactory.newInstance(); path = xpfactory.newXPath(); 

You then call the evaluate method to evaluate XPath expressions:

 String username = path.evaluate("/configuration/database/username", doc); 

You can use the same XPath object to evaluate multiple expressions.

This form of the evaluate method returns a string result. It is suitable for retrieving text, such as the text of the username node in the preceding example. If an XPath expression yields a node set, make a call such as the following:

 NodeList nodes = (NodeList) path.evaluate("/gridbag/row", doc, XPathConstants.NODESET); 

If the result is a single node, use XPathConstants.NODE instead:

 Node node = (Node) path.evaluate("/gridbag/row[1]", doc, XPathConstants.NODE); 

If the result is a number, use XPathConstants.NUMBER:

[View full width]

int count = ((Number) path.evaluate("count(/gridbag/row)", doc, XPathConstants.NUMBER)) .intValue();

You don't have to start the search at the document root. You can start the search at any node or node list. For example, if you have a node from a previous evaluation, you can call

 result = path.evaluate(expression, node); 

The program in Example 12-7 demonstrates the evaluation of XPath expressions. Load an XML file and type an expression. Select the expression type and click the Evaluate button. The result of the expression is displayed at the bottom of the frame (see Figure 12-5).

Example 12-7. XPathTest.java

[View full width]

  1. import java.awt.*;  2. import java.awt.event.*;  3. import java.io.*;  4. import javax.swing.*;  5. import javax.swing.border.*;  6. import javax.xml.namespace.*;  7. import javax.xml.parsers.*;  8. import javax.xml.xpath.*;  9. import org.w3c.dom.*;  10. import org.xml.sax.*;  11.  12. /**  13.    This program evaluates XPath expressions  14. */  15. public class XPathTest  16. {  17.    public static void main(String[] args)  18.    {  19.       JFrame frame = new XPathFrame();  20.       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  21.       frame.setVisible(true);  22.    }  23. }  24.  25. /**  26.    This frame shows an XML document, a panel to type an XPath expression,  27.    and a text field to display the result.  28. */  29. class XPathFrame extends JFrame  30. {  31.    public XPathFrame()  32.    {  33.       setTitle("XPathTest");  34.  35.       JMenu fileMenu = new JMenu("File");  36.       JMenuItem openItem = new JMenuItem("Open");  37.       openItem.addActionListener(new  38.          ActionListener()  39.          {  40.             public void actionPerformed(ActionEvent event) { openFile(); }  41.          });  42.       fileMenu.add(openItem);  43.  44.       JMenuItem exitItem = new JMenuItem("Exit");  45.       exitItem.addActionListener(new  46.          ActionListener()  47.          {  48.             public void actionPerformed(ActionEvent event) { System.exit(0); }  49.          });  50.       fileMenu.add(exitItem);  51.  52.       JMenuBar menuBar = new JMenuBar();  53.       menuBar.add(fileMenu);  54.       setJMenuBar(menuBar);  55.  56.       ActionListener listener = new  57.          ActionListener()  58.          {  59.             public void actionPerformed(ActionEvent event) { evaluate(); }  60.          };  61.       expression = new JTextField(20);  62.       expression.addActionListener(listener);  63.       JButton evaluateButton = new JButton("Evaluate");  64.       evaluateButton.addActionListener(listener);  65.  66.       typeCombo = new JComboBox(new Object[] { "STRING", "NODE", "NODESET", "NUMBER",  "BOOLEAN" });  67.       typeCombo.setSelectedItem("STRING");  68.  69.       JPanel panel = new JPanel();  70.       panel.add(expression);  71.       panel.add(typeCombo);  72.       panel.add(evaluateButton);  73.       docText = new JTextArea(10, 40);  74.       result = new JTextField();  75.       result.setBorder(new TitledBorder("Result"));  76.  77.       add(panel, BorderLayout.NORTH);  78.       add(new JScrollPane(docText), BorderLayout.CENTER);  79.       add(result, BorderLayout.SOUTH);  80.  81.       try  82.       {  83.          DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();  84.          builder = factory.newDocumentBuilder();  85.       }  86.       catch (ParserConfigurationException e)  87.       {  88.          JOptionPane.showMessageDialog(this, e);  89.       }  90.  91.       XPathFactory xpfactory = XPathFactory.newInstance();  92.       path = xpfactory.newXPath();  93.       pack();  94.    }  95.  96.    /**  97.       Open a file and load the document.  98.    */  99.    public void openFile() 100.    { 101.       JFileChooser chooser = new JFileChooser(); 102.       chooser.setCurrentDirectory(new File(".")); 103. 104.       chooser.setFileFilter(new 105.          javax.swing.filechooser.FileFilter() 106.          { 107.             public boolean accept(File f) 108.             { 109.                return f.isDirectory() || f.getName().toLowerCase().endsWith(".xml"); 110.             } 111.             public String getDescription() { return "XML files"; } 112.          }); 113.       int r = chooser.showOpenDialog(this); 114.       if (r != JFileChooser.APPROVE_OPTION) return; 115.       File f = chooser.getSelectedFile(); 116.       try 117.       { 118.          byte[] bytes = new byte[(int) f.length()]; 119.          new FileInputStream(f).read(bytes); 120.          docText.setText(new String(bytes)); 121.          doc = builder.parse(f); 122.       } 123.       catch (IOException e) 124.       { 125.          JOptionPane.showMessageDialog(this, e); 126.       } 127.       catch (SAXException e) 128.       { 129.          JOptionPane.showMessageDialog(this, e); 130.       } 131.    } 132. 133.    public void evaluate() 134.    { 135. 136.       try 137.       { 138.          String typeName = (String) typeCombo.getSelectedItem(); 139.          QName returnType = (QName) XPathConstants.class.getField(typeName).get(null); 140.          Object evalResult = path.evaluate(expression.getText(), doc, returnType); 141.          if (typeName.equals("NODESET")) 142.          { 143.             NodeList list = (NodeList) evalResult; 144.             StringBuilder builder = new StringBuilder(); 145.             builder.append("{"); 146.             for (int i = 0; i < list.getLength(); i++) 147.             { 148.                if (i > 0) builder.append(", "); 149.                builder.append("" + list.item(i)); 150.             } 151.             builder.append("}"); 152.             result.setText("" + builder); 153.          } 154.          else 155.             result.setText("" + evalResult); 156.       } 157.       catch (XPathExpressionException e) 158.       { 159.          result.setText("" + e); 160.       } 161.       catch (Exception e) // reflection exception 162.       { 163.          e.printStackTrace(); 164.       } 165.    } 166. 167.    private DocumentBuilder builder; 168.    private Document doc; 169.    private XPath path; 170.    private JTextField expression; 171.    private JTextField result; 172.    private JTextArea docText; 173.    private JComboBox typeCombo; 174. } 

Figure 12-5. Evaluating XPath expressions



 javax.xml.xpath.XPathFactory 5.0 

  • static XPathFactory newInstance()

    returns an XPathFactory instance for creating XPath objects.

  • XPath newXpath()

    constructs an XPath object for evaluating XPath expressions.


 javax.xml.xpath.XPath 5.0 

  • String evaluate(String expression, Object startingPoint)

    evaluates an expression, beginning with the given starting point. The starting point can be a node or node list. If the result is a node or node set, then the returned string consists of the data of all text node children.

  • Object evaluate(String expression, Object startingPoint, QName resultType)

    evaluates an expression, beginning with the given starting point. The starting point can be a node or node list. The resultType is one of the constants STRING, NODE, NODESET, NUMBER, or BOOLEAN in the XPathConstants class. The return value is a String, Node, NodeList, Number, or Boolean.



    Core JavaT 2 Volume II - Advanced Features
    Building an On Demand Computing Environment with IBM: How to Optimize Your Current Infrastructure for Today and Tomorrow (MaxFacts Guidebook series)
    ISBN: 193164411X
    EAN: 2147483647
    Year: 2003
    Pages: 156
    Authors: Jim Hoskins

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net