package nl.joshuaslik.tudelft.UFMGame.util.xml; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.LinkedHashMap; import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.DefaultHandler; import org.xml.sax.helpers.XMLReaderFactory; /** * class for the saxparser * * @author <a href="http://www.joshuaslik.nl/" target="_blank">Joshua Slik</a> * */ public class SAXParser extends DefaultHandler { private XMLFile file = null; private ArrayList<XMLTag> tagstack = new ArrayList<XMLTag>(); private boolean inElement = false; /* * public SAXParser() { } */ /** * parsing a file as an xml file * * @param filename * is a string for the name of the xml file * @return the xml file */ public static XMLFile parseFile(String filename) { filename = filename.replace("\\", "/"); XMLReader xr = null; try { xr = XMLReaderFactory.createXMLReader(); } catch (SAXException e) { e.printStackTrace(); } SAXParser handler = new SAXParser(); xr.setContentHandler(handler); xr.setErrorHandler(handler); InputStream is = Class.class.getResourceAsStream(filename); try { xr.parse(new InputSource(is)); } catch (IOException | NullPointerException e) { System.err.println("File \"" + filename + "\" does not exist"); } catch (SAXException e) { System.err.println("Something went wrong parsing the file: \"" + filename + "\""); System.err.println(e.getMessage()); } return handler.getXMLFile(); } /** * parsing a local xml file * * @param filename * name of the xml file * @return the xml file */ public static XMLFile parseLocalFile(String filename) { XMLReader xr = null; try { xr = XMLReaderFactory.createXMLReader(); } catch (SAXException e) { e.printStackTrace(); } SAXParser handler = new SAXParser(); xr.setContentHandler(handler); xr.setErrorHandler(handler); InputStream is = null; try { is = new FileInputStream(new File(filename)); } catch (FileNotFoundException e1) { System.err.println("File \"" + filename + "\" does not exist"); System.err.println(e1.getMessage()); } try { xr.parse(new InputSource(is)); } catch (IOException | NullPointerException e) { System.err.println("File \"" + filename + "\" does not exist"); } catch (SAXException e) { System.err.println("Something went wrong parsing the file: \"" + filename + "\""); System.err.println(e.getMessage()); } return handler.getXMLFile(); } /** * parsing a local xml file as a string * * @param xmlstring * is a string with the xml in it * @return the xml file */ public static XMLFile parseString(String xmlstring) { XMLReader xr = null; try { xr = XMLReaderFactory.createXMLReader(); } catch (SAXException e) { e.printStackTrace(); } SAXParser handler = new SAXParser(); xr.setContentHandler(handler); xr.setErrorHandler(handler); InputStream is = new ByteArrayInputStream( xmlstring.getBytes(StandardCharsets.UTF_8)); try { xr.parse(new InputSource(is)); } catch (IOException e) { System.err.println(e.getMessage()); } catch (SAXException e) { System.err.println("Something went wrong parsing your string."); System.err.println(e.getMessage()); } return handler.getXMLFile(); } // ////////////////////////////////////////////////////////////////// // Event handlers. // ////////////////////////////////////////////////////////////////// public void startDocument() { // System.out.println("Start document"); } public void endDocument() { // System.out.println("End document"); this.file = new XMLFile(tagstack.get(0)); } public void startElement(String uri, String name, String qName, Attributes atts) { // Default behaviour // if ("".equals(uri)) { // System.out.println("Start element: " + qName); // for (int i = 0; i < atts.getLength(); i++) { // System.out.println(" Attribute : " + atts.getQName(i) + "=\"" // + atts.getValue(i) + "\""); // } // } else { // System.out.println("Start element: {" + uri + "}" + name); // } // My behaviour this.inElement = true; // Generate HashMap for the attributes LinkedHashMap<String, String> attributes = new LinkedHashMap<String, String>(); for (int i = 0; i < atts.getLength(); i++) { attributes.put(atts.getQName(i), atts.getValue(i)); } // Create new XMLTag and push it onto the stack XMLTag current = new XMLTag(qName, attributes); tagstack.add(current); } public void endElement(String uri, String name, String qName) { // Default behaviour // if ("".equals(uri)) // System.out.println("End element: " + qName); // else // System.out.println("End element: {" + uri + "}" + name); // My behaviour /* * Element has ended, we are no longer inside an element This has been * added because after endElement is called, the parser calls the * characters() method again, and we don't want it to run, because it * will override the previous content with nothing. */ this.inElement = false; // Pop the current XMLTag off the stack (only if it is not the root // element) if (tagstack.size() > 1) { XMLTag ended = tagstack.remove(tagstack.size() - 1); tagstack.get(tagstack.size() - 1).addElement(ended); } } public void characters(char ch[], int start, int length) { if (this.inElement == true) { // System.out.print(" Characters: \""); String content = ""; for (int i = start; i < start + length; i++) { switch (ch[i]) { case '\\': // System.out.print("\\\\"); // content = content + "\\\\"; break; case '"': // System.out.print("\\\""); // content = content + "\\\""; break; case '\n': // System.out.print("\\n"); // content = content + "\\n"; break; case '\r': // System.out.print("\\r"); // content = content + "\\r"; break; case '\t': // System.out.print("\\t"); // content = content + "\\t"; break; default: // System.out.print(ch[i]); content = content + ch[i]; break; } } // System.out.println("Characters: " + content); // System.out.println(tagstack.get(tagstack.size() - 1).getName()); tagstack.get(tagstack.size() - 1).setContent(content); // System.out.print("\n"); // System.out.print("\"\n"); } } private XMLFile getXMLFile() { return file; } }