jdom解析xml

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);
         }
      }
    }


原文地址:https://www.cnblogs.com/daichangya/p/12959345.html