Ficha de Trabalho nº6 Curso de Especialização Tecnológica Tecnologia e Programação de Sistemas de Informação 3ª Edição Componente de formação: Integração de SI Ferramentas Introdução Java XML Stax (Streaming API for XML) é uma API para leitura e escrita de documentos XML. O JAXB define uma API para o programador para leitura e escrita de objetos de documentos XML. O Stax tem duas categorias: Cursor API Event Interator API Tem duas interfaces principais: XML EventReader, para analisar XML e o XMLEventWriter para gerar XML. As aplicações podem usar qualquer uma destas para análise de documentos XML. 1. XMLEventReader - Read XML Example O Exemplo seguinte é sobre aplicações que fazem loop a todo o documento solicitando o próximo evento. O Event Iterator é implementado sobre o Cursor API. No seguinte exemplo o documento XML é lido e posteriormente são criados os objetos. <?xml version="1.0" encoding="utf-8"?> <config> <item date="january 2009"> <mode>1</mode> <unit>900</unit> <current>1</current> <interactive>1</interactive> </item> <item date="february 2009"> <mode>2</mode> <unit>400</unit> <current>2</current> <interactive>5</interactive> Prof. Isabel Marques 1
</item> <item date="december 2009"> <mode>9</mode> <unit>5</unit> <current>100</current> <interactive>3</interactive> </item> </config> Prof. Isabel Marques 2
Ficha de Trabalho nº6 Curso de Especialização Tecnológica Tecnologia e Programação de Sistemas de Informação 3ª Edição Criando a classe para armazenar os registos do ficheiro XML. package de.vogella.xml.stax.model; public class Item { private String date; private String mode; private String unit; private String current; private String interactive; public String getdate() { return date; public void setdate(string date) { this.date = date; public String getmode() { return mode; public void setmode(string mode) { this.mode = mode; public String getunit() { return unit; public void setunit(string unit) { this.unit = unit; public String getcurrent() { Prof. Isabel Marques 3
return current; public void setcurrent(string current) { this.current = current; public String getinteractive() { return interactive; public void setinteractive(string interactive) { this.interactive = interactive; @Override public String tostring() { return "Item [current=" + current + ", date=" + date + ", interactive=" + interactive + ", mode=" + mode + ", unit=" + unit + "]"; O seguinte código lê o ficheiro XML e cria uma lista de objetos. package de.vogella.xml.stax.read; import java.io.fileinputstream; import java.io.filenotfoundexception; import java.io.inputstream; import java.util.arraylist; import java.util.iterator; import java.util.list; import javax.xml.stream.xmleventreader; import javax.xml.stream.xmlinputfactory; import javax.xml.stream.xmlstreamexception; import javax.xml.stream.events.attribute; Prof. Isabel Marques 4
Ficha de Trabalho nº6 Curso de Especialização Tecnológica Tecnologia e Programação de Sistemas de Informação 3ª Edição import javax.xml.stream.events.endelement; import javax.xml.stream.events.startelement; import javax.xml.stream.events.xmlevent; import de.vogella.xml.stax.model.item; public class StaXParser { static final String DATE = "date"; static final String ITEM = "item"; static final String MODE = "mode"; static final String UNIT = "unit"; static final String CURRENT = "current"; static final String INTERACTIVE = "interactive"; @SuppressWarnings({ "unchecked", "null" ) public List<Item> readconfig(string configfile) { List<Item> items = new ArrayList<Item>(); try { // First, create a new XMLInputFactory XMLInputFactory inputfactory = XMLInputFactory.newInstance(); // Setup a new eventreader InputStream in = new FileInputStream(configFile); XMLEventReader eventreader = inputfactory.createxmleventreader(in); // read the XML document Item item = null; while (eventreader.hasnext()) { XMLEvent event = eventreader.nextevent(); if (event.isstartelement()) { StartElement startelement = event.asstartelement(); // If we have an item element, we create a new item Prof. Isabel Marques 5
if (startelement.getname().getlocalpart() == (ITEM)) { item = new Item(); // We read the attributes from this tag and add the date // attribute to our object Iterator<Attribute> attributes = startelement.getattributes(); while (attributes.hasnext()) { Attribute attribute = attributes.next(); if (attribute.getname().tostring().equals(date)) { item.setdate(attribute.getvalue()); if (event.isstartelement()) { if (event.asstartelement().getname().getlocalpart().equals(mode)) { event = eventreader.nextevent(); item.setmode(event.ascharacters().getdata()); continue; if (event.asstartelement().getname().getlocalpart().equals(unit)) { event = eventreader.nextevent(); item.setunit(event.ascharacters().getdata()); continue; if (event.asstartelement().getname().getlocalpart().equals(current)) { event = eventreader.nextevent(); item.setcurrent(event.ascharacters().getdata()); continue; Prof. Isabel Marques 6
Ficha de Trabalho nº6 Curso de Especialização Tecnológica Tecnologia e Programação de Sistemas de Informação 3ª Edição if (event.asstartelement().getname().getlocalpart().equals(interactive)) { event = eventreader.nextevent(); item.setinteractive(event.ascharacters().getdata()); continue; // If we reach the end of an item element, we add it to the list if (event.isendelement()) { EndElement endelement = event.asendelement(); if (endelement.getname().getlocalpart() == (ITEM)) { items.add(item); catch (FileNotFoundException e) { e.printstacktrace(); catch (XMLStreamException e) { e.printstacktrace(); return items; Com o seguinte código testa o programa. Não esquecer que o ficheiro config.xml deve existir na pasta project. package de.vogella.xml.stax.read; Prof. Isabel Marques 7
import java.util.list; import de.vogella.xml.stax.model.item; public class TestRead { public static void main(string args[]) { StaXParser read = new StaXParser(); List<Item> readconfig = read.readconfig("config.xml"); for (Item item : readconfig) { System.out.println(item); 2. Write XML File Example Assuma que pretende escrever o seguinte ficheiro XML. <?xml version="1.0" encoding="utf-8"?> <config> <mode>1</mode> <unit>900</unit> <current>1</current> <interactive>1</interactive> </config> StaX não providencia funcionalidade para formatar automaticamente o ficheiro XML, para tal, é necessário adicionar end-of-lines e tab informations ao ficheiro XML. package de.vogella.xml.stax.writer; import java.io.fileoutputstream; import javax.xml.stream.xmleventfactory; import javax.xml.stream.xmleventwriter; import javax.xml.stream.xmloutputfactory; Prof. Isabel Marques 8
Ficha de Trabalho nº6 Curso de Especialização Tecnológica Tecnologia e Programação de Sistemas de Informação 3ª Edição import javax.xml.stream.xmlstreamexception; import javax.xml.stream.events.characters; import javax.xml.stream.events.endelement; import javax.xml.stream.events.startdocument; import javax.xml.stream.events.startelement; import javax.xml.stream.events.xmlevent; public class StaxWriter { private String configfile; public void setfile(string configfile) { this.configfile = configfile; public void saveconfig() throws Exception { // create an XMLOutputFactory XMLOutputFactory outputfactory = XMLOutputFactory.newInstance(); // create XMLEventWriter XMLEventWriter eventwriter = outputfactory.createxmleventwriter(new FileOutputStream(configFile)); // create an EventFactory XMLEventFactory eventfactory = XMLEventFactory.newInstance(); XMLEvent end = eventfactory.createdtd("\n"); // create and write Start Tag StartDocument startdocument = eventfactory.createstartdocument(); eventwriter.add(startdocument); // create config open tag StartElement configstartelement = eventfactory.createstartelement("", "", "config"); eventwriter.add(configstartelement); eventwriter.add(end); Prof. Isabel Marques 9
// Write the different nodes createnode(eventwriter, "mode", "1"); createnode(eventwriter, "unit", "901"); createnode(eventwriter, "current", "0"); createnode(eventwriter, "interactive", "0"); eventwriter.add(eventfactory.createendelement("", "", "config")); eventwriter.add(end); eventwriter.add(eventfactory.createenddocument()); eventwriter.close(); private void createnode(xmleventwriter eventwriter, String name, String value) throws XMLStreamException { XMLEventFactory eventfactory = XMLEventFactory.newInstance(); XMLEvent end = eventfactory.createdtd("\n"); XMLEvent tab = eventfactory.createdtd("\t"); // create Start node StartElement selement = eventfactory.createstartelement("", "", name); eventwriter.add(tab); eventwriter.add(selement); // create Content Characters characters = eventfactory.createcharacters(value); eventwriter.add(characters); // create End node EndElement eelement = eventfactory.createendelement("", "", name); eventwriter.add(eelement); eventwriter.add(end); De seguida um pequeno teste: Prof. Isabel Marques 10
Ficha de Trabalho nº6 Curso de Especialização Tecnológica Tecnologia e Programação de Sistemas de Informação 3ª Edição package de.vogella.xml.stax.writer; public class TestWrite { public static void main(string[] args) { StaxWriter configfile = new StaxWriter(); configfile.setfile("config2.xml"); try { configfile.saveconfig(); catch (Exception e) { e.printstacktrace(); XPATH É uma linguagem para procurar/selecionar nós de um documento XML. O Java 5 introduziu o java.xml.xpath que fornece a libraria XPath. O seguinte exemplo explica como utilizar o XPath para manipular um documento XML via Java. Criando o seguinte ficheiro XML, temos: <?xml version="1.0" encoding="utf-8"?> <people> <person> <firstname>lars</firstname> <lastname>vogel</lastname> <city>heidelberg</city> </person> <person> <firstname>jim</firstname> Prof. Isabel Marques 11
<lastname>knopf</lastname> <city>heidelberg</city> </person> <person> <firstname>lars</firstname> <lastname>strangelastname</lastname> <city>london</city> </person> <person> <firstname>landerman</firstname> <lastname>petrelli</lastname> <city>somewhere</city> </person> <person> <firstname>lars</firstname> <lastname>tim</lastname> <city>somewhereelse</city> </person> </people> Crie uma nova package myxml e uma nova class QueryXML. package myxml; import java.io.ioexception; import javax.xml.parsers.documentbuilder; import javax.xml.parsers.documentbuilderfactory; import javax.xml.parsers.parserconfigurationexception; import javax.xml.xpath.xpath; import javax.xml.xpath.xpathconstants; import javax.xml.xpath.xpathexpression; import javax.xml.xpath.xpathexpressionexception; import javax.xml.xpath.xpathfactory; Prof. Isabel Marques 12
Ficha de Trabalho nº6 Curso de Especialização Tecnológica Tecnologia e Programação de Sistemas de Informação 3ª Edição import org.w3c.dom.document; import org.w3c.dom.nodelist; import org.xml.sax.saxexception; public class QueryXML { public void query() throws ParserConfigurationException, SAXException, IOException, XPathExpressionException { // standard for reading an XML file DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setnamespaceaware(true); DocumentBuilder builder; Document doc = null; XPathExpression expr = null; builder = factory.newdocumentbuilder(); doc = builder.parse("person.xml"); // create an XPathFactory XPathFactory xfactory = XPathFactory.newInstance(); // create an XPath object XPath xpath = xfactory.newxpath(); // compile the XPath expression expr = xpath.compile("//person[firstname='lars']/lastname/text()"); // run the query and get a nodeset Object result = expr.evaluate(doc, XPathConstants.NODESET); // cast the result to a DOM NodeList NodeList nodes = (NodeList) result; for (int i=0; i<nodes.getlength();i++){ System.out.println(nodes.item(i).getNodeValue()); Prof. Isabel Marques 13
// new XPath expression to get the number of people with name Lars expr = xpath.compile("count(//person[firstname='lars'])"); // run the query and get the number of nodes Double number = (Double) expr.evaluate(doc, XPathConstants.NUMBER); System.out.println("Number of objects " +number); // do we have more than 2 people with name Lars? expr = xpath.compile("count(//person[firstname='lars']) >2"); // run the query and get the number of nodes Boolean check = (Boolean) expr.evaluate(doc, XPathConstants.BOOLEAN); System.out.println(check); public static void main(string[] args) throws XPathExpressionException, ParserConfigurationException, SAXException, IOException { QueryXML process = new QueryXML(); process.query(); Bom trabalho! Prof. Isabel Marques 14