jdom解析xml

来源:互联网 发布:手机突然没有4g网络 编辑:程序博客网 时间:2024/06/09 09:08
A typical Java application is a domain-specific XML editor:
  • nobody wants to write the markup by hand
  • general-purpose XML editors are too clunky
We generalize the business card language to allow collections of business cards:

<cards>  <card>    <name>John Doe</name>    <title>CEO, Widget Inc.</title>    <email>john.doe@widget.com</email>    <phone>(202) 456-1414</phone>    <logo url="widget.gif" />  </card>  <card>    <name>Michael Schwartzbach</name>    <title>Associate Professor</title>    <email>mis@brics.dk</email>    <phone>+45 8610 8790</phone>    <logo url="http://www.brics.dk/~mis/portrait.gif" />  </card>  <card>    <name>Anders Møller</name>    <title>Research Assistant Professor</title>    <email>amoeller@brics.dk</email>    <phone>+45 8942 3475</phone>    <logo url="http://www.brics.dk/~amoeller/am.jpg"/>  </card></cards>

We then write a Java program to edit such collections.

First, we need a high-level representation of a business card:

class Card {  public String name, title, email, phone, logo;  public Card(String name, String title, String email, String phone, String logo) {    this.name = name;    this.title = title;    this.email = email;    this.phone = phone;    this.logo = logo;  }}

An XML document must then be translated into a vector of such objects:

Vector doc2vector(Document d) {  Vector v = new Vector();  Iterator i = d.getRootElement().getChildren().iterator();  while (i.hasNext()) {    Element e = (Element)i.next();    String phone = e.getChildText("phone");    if (phone==null) phone="";    Element logo = e.getChild("logo");    String url;    if (logo==null) url = ""; else url = logo.getAttributeValue("url");    Card c = new Card(e.getChildText("name"),  // exploit schema,                      e.getChildText("title"), // assume validity                      e.getChildText("email"),                      phone,                      url);    v.add(c);  }  return v;}

And back into an XML document:

Document vector2doc() {  Element cards = new Element("cards");  for (int i=0; i<cardvector.size(); i++) {    Card c = (Card)cardvector.elementAt(i);    if (c!=null) {      Element card = new Element("card");      Element name = new Element("name");      name.addContent(c.name);      card.addContent(name);      Element title = new Element("title");      title.addContent(c.title);      card.addContent(title);      Element email = new Element("email");      email.addContent(c.email);      card.addContent(email);      if (!c.phone.equals("")) {        Element phone = new Element("phone");        phone.addContent(c.phone);        card.addContent(phone);      }      if (!c.logo.equals("")) {        Element logo = new Element("logo");        logo.setAttribute("url",c.logo);        card.addContent(logo);      }      cards.addContent(card);    }  }  return new Document(cards);}

A little logic and some GUI then completes the editor:

GUI

Compile with: javac -classpath xerces.jar:jdom.jar BCedit.java

This example contains some general observations:

  • XML documents are parsed via JDOM into domain-specific data structures
  • if the input is known to validate according to some schema, then many runtime errors can be assumed never to occur
  • how do we ensure that the output of vector2doc is valid according to the schema? (well-formedness is for free) 
    - that's a current research challenge!
  • import java.awt.*;import java.awt.event.*;import java.io.*; import java.util.*;import org.jdom.*; import org.jdom.input.*; import org.jdom.output.*; class Card {  public String name, title, email, phone, logo;  public Card(String name, String title, String email, String phone, String logo) {    this.name = name;    this.title = title;    this.email = email;    this.phone = phone;    this.logo = logo;  }}public class BCedit extends Frame implements ActionListener {  Button ok = new Button("ok");  Button delete = new Button("delete");  Button clear = new Button("clear");  Button save = new Button("save");  Button quit = new Button("quit");  TextField name = new TextField(20);  TextField title = new TextField(20);  TextField email = new TextField(20);  TextField phone = new TextField(20);  TextField logo = new TextField(20);  Panel cardpanel = new Panel(new GridLayout(0,1));  String cardfile;  Vector cardvector;  int current = -1;  public static void main(String[] args) { new BCedit(args[0]); }  Vector doc2vector(Document d) {    Vector v = new Vector();    Iterator i = d.getRootElement().getChildren().iterator();    while (i.hasNext()) {      Element e = (Element)i.next();      String phone = e.getChildText("phone");      if (phone==null) phone="";      Element logo = e.getChild("logo");      String url;      if (logo==null) url=""; else url=logo.getAttributeValue("url");      Card c = new Card(e.getChildText("name"),                        e.getChildText("title"),                        e.getChildText("email"),                        phone,                        url);      v.add(c);    }    return v;  }  Document vector2doc() {    Element cards = new Element("cards");    for (int i=0; i<cardvector.size(); i++) {      Card c = (Card)cardvector.elementAt(i);      if (c!=null) {        Element card = new Element("card");        Element name = new Element("name");        name.addContent(c.name);        card.addContent(name);        Element title = new Element("title");        title.addContent(c.title);        card.addContent(title);        Element email = new Element("email");        email.addContent(c.email);        card.addContent(email);        if (!c.phone.equals("")) {          Element phone = new Element("phone");          phone.addContent(c.phone);          card.addContent(phone);        }        if (!c.logo.equals("")) {          Element logo = new Element("logo");          logo.setAttribute("url",c.logo);          card.addContent(logo);        }        cards.addContent(card);      }    }    return new Document(cards);  }  void addCards() {    cardpanel.removeAll();    for (int i=0; i<cardvector.size(); i++) {      Card c = (Card)cardvector.elementAt(i);      if (c!=null) {        Button b = new Button(c.name);        b.setActionCommand(String.valueOf(i));        b.addActionListener(this);        cardpanel.add(b);      }    }    this.pack();  }  public BCedit(String cardfile) {    super("BCedit");    this.cardfile=cardfile;    try {      cardvector = doc2vector(new SAXBuilder().build(new File(cardfile)));    } catch (Exception e) {e.printStackTrace();}    this.setLayout(new BorderLayout());    ScrollPane s = new ScrollPane();    s.setSize(200,0);    s.add(cardpanel);    this.add(s,BorderLayout.WEST);    Panel l = new Panel(new GridLayout(5,1));    l.add(new Label("Name"));                      l.add(new Label("Title"));                      l.add(new Label("Email"));                      l.add(new Label("Phone"));                      l.add(new Label("Logo"));                      this.add(l,BorderLayout.CENTER);    Panel f = new Panel(new GridLayout(5,1));    f.add(name);        f.add(title);        f.add(email);        f.add(phone);        f.add(logo);        this.add(f,BorderLayout.EAST);    Panel p = new Panel();    ok.addActionListener(this);    p.add(ok);    delete.addActionListener(this);    p.add(delete);    clear.addActionListener(this);    p.add(clear);    save.addActionListener(this);    p.add(save);    quit.addActionListener(this);    p.add(quit);    this.add(p,BorderLayout.SOUTH);    addCards();    this.show();  }  public void actionPerformed(ActionEvent event) {     Card c;     String command = event.getActionCommand();     if (command.equals("ok")) {       c = new Card(name.getText(),                    title.getText(),                    email.getText(),                    phone.getText(),                    logo.getText());       if (current==-1) {          cardvector.add(c);       } else {          cardvector.setElementAt(c,current);       }       addCards();     } else if (command.equals("delete")) {        if (current!=-1) {          cardvector.setElementAt(null,current);          addCards();        }     } else if (command.equals("clear")) {        current = -1;        name.setText("");        title.setText("");        email.setText("");        phone.setText("");        logo.setText("");     } else if (command.equals("save")) {        try {          new XMLOutputter().output(vector2doc(),new FileOutputStream(cardfile));        } catch (Exception e) {e.printStackTrace();}     } else if (command.equals("quit")) {        System.exit(0);     } else {        current = Integer.parseInt(command);        c = (Card)cardvector.elementAt(current);        name.setText(c.name);        title.setText(c.title);        email.setText(c.email);        phone.setText(c.phone);        logo.setText(c.logo);     }  }}


原创粉丝点击