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.

8 thoughts on “Parsing a XML Sandwich with JavaFX

  1. thank you for this tutorial!!! great job:)
    but can we get an example about the other sense, i mean to write date from javaFX to XML file? thanks in advance

  2. Hi
    i’m beginer in java FX, i’ve tried to create the parser function to get data from Xml file i got the same error message:

    java.lang.NoSuchMethodException: newpackage.NewJavaFXClass.javafx$run$(com.sun.javafx.runtime.sequence.Sequence)
    at java.lang.Class.getMethod(Unknown Source)
    at com.sun.javafx.runtime.Entry.start(Entry.java:63)
    at com.sun.javafx.runtime.Main.main(Main.java:80)

    i’m trying to get the data from the XML file and save them into a public variable so i can use them in other classes.
    bellow is the function that i’m using:
    import javafx.data.pull.*;
    import java.io.FileInputStream;
    import java.lang.System;
    import javafx.data.xml.QName;

    public function loadData( ): Void{
    var imageURL8 : String [] = [ “” ];
    var myparser = PullParser {
    documentType: PullParser.XML;
    onEvent: function (e: Event) {
    // starter xml elements
    if(e.type == PullParser.START_ELEMENT){
    // Carousel
    if(e.qname.name.equals(“Carousel”)){
    System.out.println(“Carousel”);
    }

    // PrincipalService
    if(e.qname.name.equals(“PrincipalService”)){
    System.out.println(“PrincipalService”);
    }

    // Image
    if(e.qname.name.equals(“Image”)){
    System.out.println(“Image”);
    }

    // Label
    if(e.qname.name.equals(“Label”)){
    System.out.println(“Label”);
    }

    // ImageLink
    if(e.qname.name.equals(“ImageLink”)){
    System.out.println(“ImageLink”);
    }
    for (i in [1..5]){
    if(e.qname.name.equals(“Url{i}”)){
    imageURL8[i]= e.getAttributeValue(QName{name:”Address”});
    System.out.println(imageURL8[i]);
    }
    }

    // description
    if(e.qname.name.equals(“description”)){
    var type= e.getAttributeValue(QName{name:”type”});
    System.out.println(type);
    if(type.equals(“long”)){
    System.out.println(“ok”);

    } else {

    }
    }
    }

    // ending xml elements
    if(e.type == PullParser.END_ELEMENT){
    if(e.qname.name.equals(“data”)){

    }
    }
    }
    input: new FileInputStream(“/Parametter.xml”);
    }
    myparser.parse();

    }

    Can any body help me to solve this problem as soon as possible.

    other thing that’s not related to this, but it’s closer, how can we save data from JavaFX to an XML file

    (i’m using Netbeans 6.9 with JavaFX 1.3)
    thank you in advance for your help

Leave a Reply

Your email address will not be published. Required fields are marked *