This program evaluates XPath expressions
/*
This program is a part of the companion code for Core Java 8th ed.
(http://horstmann.com/corejava)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.xml.namespace.*;
import javax.xml.parsers.*;
import javax.xml.xpath.*;
import org.w3c.dom.*;
import org.xml.sax.*;
/**
* This program evaluates XPath expressions
* @version 1.01 2007-06-25
* @author Cay Horstmann
*/
public class XPathTest
{
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
JFrame frame = new XPathFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
}
/**
* This frame shows an XML document, a panel to type an XPath expression, and a text field to
* display the result.
*/
class XPathFrame extends JFrame
{
public XPathFrame()
{
setTitle("XPathTest");
JMenu fileMenu = new JMenu("File");
JMenuItem openItem = new JMenuItem("Open");
openItem.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
openFile();
}
});
fileMenu.add(openItem);
JMenuItem exitItem = new JMenuItem("Exit");
exitItem.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
System.exit(0);
}
});
fileMenu.add(exitItem);
JMenuBar menuBar = new JMenuBar();
menuBar.add(fileMenu);
setJMenuBar(menuBar);
ActionListener listener = new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
evaluate();
}
};
expression = new JTextField(20);
expression.addActionListener(listener);
JButton evaluateButton = new JButton("Evaluate");
evaluateButton.addActionListener(listener);
typeCombo = new JComboBox(new Object[] { "STRING", "NODE", "NODESET", "NUMBER", "BOOLEAN" });
typeCombo.setSelectedItem("STRING");
JPanel panel = new JPanel();
panel.add(expression);
panel.add(typeCombo);
panel.add(evaluateButton);
docText = new JTextArea(10, 40);
result = new JTextField();
result.setBorder(new TitledBorder("Result"));
add(panel, BorderLayout.NORTH);
add(new JScrollPane(docText), BorderLayout.CENTER);
add(result, BorderLayout.SOUTH);
try
{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
builder = factory.newDocumentBuilder();
}
catch (ParserConfigurationException e)
{
JOptionPane.showMessageDialog(this, e);
}
XPathFactory xpfactory = XPathFactory.newInstance();
path = xpfactory.newXPath();
pack();
}
/**
* Open a file and load the document.
*/
public void openFile()
{
JFileChooser chooser = new JFileChooser();
chooser.setCurrentDirectory(new File("."));
chooser.setFileFilter(new javax.swing.filechooser.FileFilter()
{
public boolean accept(File f)
{
return f.isDirectory() || f.getName().toLowerCase().endsWith(".xml");
}
public String getDescription()
{
return "XML files";
}
});
int r = chooser.showOpenDialog(this);
if (r != JFileChooser.APPROVE_OPTION) return;
File f = chooser.getSelectedFile();
try
{
byte[] bytes = new byte[(int) f.length()];
new FileInputStream(f).read(bytes);
docText.setText(new String(bytes));
doc = builder.parse(f);
}
catch (IOException e)
{
JOptionPane.showMessageDialog(this, e);
}
catch (SAXException e)
{
JOptionPane.showMessageDialog(this, e);
}
}
public void evaluate()
{
try
{
String typeName = (String) typeCombo.getSelectedItem();
QName returnType = (QName) XPathConstants.class.getField(typeName).get(null);
Object evalResult = path.evaluate(expression.getText(), doc, returnType);
if (typeName.equals("NODESET"))
{
NodeList list = (NodeList) evalResult;
StringBuilder builder = new StringBuilder();
builder.append("{");
for (int i = 0; i < list.getLength(); i++)
{
if (i > 0) builder.append(", ");
builder.append("" + list.item(i));
}
builder.append("}");
result.setText("" + builder);
}
else result.setText("" + evalResult);
}
catch (XPathExpressionException e)
{
result.setText("" + e);
}
catch (Exception e) // reflection exception
{
e.printStackTrace();
}
}
private DocumentBuilder builder;
private Document doc;
private XPath path;
private JTextField expression;
private JTextField result;
private JTextArea docText;
private JComboBox typeCombo;
}
//gridbag.dtd
<!ELEMENT gridbag (row)*>
<!ELEMENT row (cell)*>
<!ELEMENT cell (bean)>
<!ATTLIST cell gridx CDATA #IMPLIED>
<!ATTLIST cell gridy CDATA #IMPLIED>
<!ATTLIST cell gridwidth CDATA "1">
<!ATTLIST cell gridheight CDATA "1">
<!ATTLIST cell weightx CDATA "0">
<!ATTLIST cell weighty CDATA "0">
<!ATTLIST cell fill (NONE|BOTH|HORIZONTAL|VERTICAL) "NONE">
<!ATTLIST cell anchor
(CENTER|NORTH|NORTHEAST|EAST|SOUTHEAST|SOUTH|SOUTHWEST|WEST|NORTHWEST) "CENTER">
<!ATTLIST cell ipadx CDATA "0">
<!ATTLIST cell ipady CDATA "0">
<!ELEMENT bean (class, property*)>
<!ATTLIST bean id ID #IMPLIED>
<!ELEMENT class (#PCDATA)>
<!ELEMENT property (name, value)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT value (int|string|boolean|bean)>
<!ELEMENT int (#PCDATA)>
<!ELEMENT string (#PCDATA)>
<!ELEMENT boolean (#PCDATA)>
//File fontdialog.xml
<?xml version="1.0"?>
<!DOCTYPE gridbag SYSTEM "gridbag.dtd">
<gridbag>
<row>
<cell anchor="EAST">
<bean>
<class>javax.swing.JLabel</class>
<property>
<name>text</name>
<value><string>Face: </string></value>
</property>
</bean>
</cell>
<cell fill="HORIZONTAL" weightx="100">
<bean id="face">
<class>javax.swing.JComboBox</class>
</bean>
</cell>
<cell gridheight="4" fill="BOTH" weightx="100" weighty="100">
<bean id="sample">
<class>javax.swing.JTextArea</class>
<property>
<name>text</name>
<value><string>The quick brown fox jumps over the lazy dog</string></value>
</property>
<property>
<name>editable</name>
<value><boolean>false</boolean></value>
</property>
<property>
<name>lineWrap</name>
<value><boolean>true</boolean></value>
</property>
<property>
<name>border</name>
<value>
<bean>
<class>javax.swing.border.EtchedBorder</class>
</bean>
</value>
</property>
</bean>
</cell>
</row>
<row>
<cell anchor="EAST">
<bean>
<class>javax.swing.JLabel</class>
<property>
<name>text</name>
<value><string>Size: </string></value>
</property>
</bean>
</cell>
<cell fill="HORIZONTAL" weightx="100">
<bean id="size">
<class>javax.swing.JComboBox</class>
</bean>
</cell>
</row>
<row>
<cell gridwidth="2" weighty="100">
<bean id="bold">
<class>javax.swing.JCheckBox</class>
<property>
<name>text</name>
<value><string>Bold</string></value>
</property>
</bean>
</cell>
</row>
<row>
<cell gridwidth="2" weighty="100">
<bean id="italic">
<class>javax.swing.JCheckBox</class>
<property>
<name>text</name>
<value><string>Italic</string></value>
</property>
</bean>
</cell>
</row>
</gridbag>
Related examples in the same category