Skip to content

Tag: parser

Parsing a XML Sandwich with JavaFX

delicious sandwich

Let sandwich.xml be a file at /tmp directory with the content above.

<?xml version="1.0" encoding="UTF-8"?>
 
<bread sesame="true">
   <catchup/>
   <hamburguer/>
   <cheese type="chedar"/>
   <maionese/>
   <lettuce/>
</bread>

We can open it using java.io.FileInputStream and so use it on a javafx.data.pull.PullParser. A PullParser is a event oriented parser that works with XML and YAML files. Above a general and simple parser with a GUI that show the list of events during the parse process.

import java.io.FileInputStream;
import javafx.data.pull.Event;
import javafx.data.pull.PullParser;
import javafx.ext.swing.SwingList;
import javafx.ext.swing.SwingListItem;
import javafx.scene.Scene;
import javafx.stage.Stage;
 
var list = SwingList { width: 600 height: 300 }
 
var myparser = PullParser {
   documentType: PullParser.XML;
   onEvent: function (e: Event) {
      var item = SwingListItem {
         text: "event {e}"
      };
      insert item into list.items;
   }
   input: new FileInputStream("/tmp/sandwich.xml");
}
myparser.parse();
 
Stage {
   title: "XML Sandwich"
   scene: Scene { content: list }
}

javafx xml sandwich

The XML cheese element produce two the outputs.

type:1 typeName:START_ELEMENT level:1 qname:cheese text:” namespaces:{} attributes:{type=chedar}
type:2 typeName:END_ELEMENT level:1 qname:cheese text:” namespaces:{} attributes:{type=chedar}

Notice that white spaces like tab and escape characters like new line also produced events from type TEXT. We are not interested on them. Above a parser that looks only those events of type START_ELEMENT or END_ELEMENT, look into it’s contents, building a sandwich at runtime based on the XML file.

import java.io.FileInputStream;
import javafx.data.pull.Event;
import javafx.data.pull.PullParser;
import javafx.data.xml.QName;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.VBox;
import javafx.scene.Scene;
import javafx.stage.Stage;
 
// my sandwich starts as an empty VBox
var mysandwich = VBox {}
 
// give a name and returns a ImageView with a png image like the name
function ingredient(name){
   return ImageView {
      image: Image {
         url: "{__DIR__}{name}.png"
      }
   }
}
 
// basicaly, look the event and put a ingredient at mysandwich
var myparser = PullParser {
   documentType: PullParser.XML;
   onEvent: function (e: Event) {
      // starter xml elements
      if(e.type == PullParser.START_ELEMENT){
         // bread
         if(e.qname.name.equals("bread")){
             insert ingredient("bread_top") into mysandwich.content;
         }
 
         // hamburguer
         if(e.qname.name.equals("hamburguer")){
             insert ingredient("hamburguer") into mysandwich.content;
         }
 
         // catchup
         if(e.qname.name.equals("catchup")){
             insert ingredient("catchup") into mysandwich.content;
         }
 
         // maionese
         if(e.qname.name.equals("maionese")){
             insert ingredient("maionese") into mysandwich.content;
         }
 
         // lettuce
         if(e.qname.name.equals("lettuce")){
             insert ingredient("lettuce") into mysandwich.content;
         }
 
         // cheese
         if(e.qname.name.equals("cheese")){
            var type= e.getAttributeValue(QName{name:"type"});
            if(type.equals("cheedar")){
                 insert ingredient("cheedar") into mysandwich.content;
            } else {
                insert ingredient("cheese") into mysandwich.content;
            }
         }
      }
 
      // ending xml elements (just bread)
      if(e.type == PullParser.END_ELEMENT){
         if(e.qname.name.equals("bread")){
            insert ingredient("bread_botton") into mysandwich.content;
         }
      }
   }
   input: new FileInputStream("/tmp/sandwich.xml");
}
myparser.parse();
 
Stage {
   title: "XML Sandwich"
   scene: Scene {
      height: 300
      content: mysandwich
   }
}

Here’s our sandwich.

sandwich javaFX

Just changing the XML file you got a new sandwich.

<?xml version="1.0" encoding="UTF-8"?>
<!-- double burger -->
<bread sesame="true">
   <maionese/>
   <lettuce/>
   <hamburguer/>
   <cheese type="chedar"/>
   <catchup/>
   <hamburguer/>
   <lettuce/>
</bread>

double burguer

Bon appétit.

For more details on XML and JSON parsing see the JavaFX API.