Discussions

XML & Web services: SAX Event Handler doesn't allow to add objects to vector

  1. Hi all! I need to generate the contents of the XML message, with the help of xerces library, then convert it to String, right now I am serializing it to the File, and then reading it back in an input source (SAXSource), then with the help of the javax.xml.transform package converting it to the String. can't I directly transform the generated XML into String without serializing to the File first. Here is the method that generates and serializes, private void buildNamesXMLFile() { try { FileOutputStream fos = new FileOutputStream("QBXMLRequest.xml"); //XERCES 1 or 2 additionnal classes. OutputFormat of = new OutputFormat(); of.setIndent(1); of.setIndenting(true); XMLSerializer serializer = new XMLSerializer(fos,of); // SAX2.0 ContentHandler. ContentHandler hd = serializer.asContentHandler(); //ContentHandler hd = new DefaultHandler(); hd.startDocument(); // Processing instruction hd.processingInstruction("qbxml","version=\"4.0\" "); // USER attributes. AttributesImpl atts = new AttributesImpl(); // USERS tag. hd.startElement("","","QBXML",atts); atts.clear(); atts.addAttribute("","","onError","CDATA","stopOnError"); hd.startElement("","","QBXMLMsgsRq",atts); .............................................. hd.endElement("","","QBXMLMsgsRq"); hd.endElement("","","QBXML"); hd.endDocument (); fos.close(); } catch(Exception e) { e.printStackTrace(); } } and here is the method to read it from File and then convert it to String, public String namesQuery() { // A call to the above method to genrate XML and serialize it to File buildNamesXMLFile(); String xml; // read File in input Source then convert it to String. try { InputSource inputSource = new InputSource("QBXMLRequest.xml"); Source source = new SAXSource(inputSource); StringWriter out = new StringWriter(); Result result = new StreamResult(out); TransformerFactory tFactory = TransformerFactory.newInstance(); Transformer transformer = tFactory.newTransformer(); transformer.transform(source, result); xml = out.toString(); } catch (Exception e) { e.printStackTrace(); return ""; } return xml; } as you can see in the above method, I am reading the XML from the file, "QBXMLRequest.xml", which is produced in the buildNamesXMLFile() method, in which i generate and serialize to the file, what I should do is generate XML and directly convert it to string, without serializing it first. The second Problem is, I am getting the response from a program in the form of a String, I convert it to XML with the help of Reader and StringReader, then parse it, and extract the element contents (characters) out of XML and storing in the vector, the following class initializes the SAX Library and parses the String XML: public class ParseNameResponse extends DefaultHandler { Vector namesList = new Vector(); public ParseNameResponse() { super(); } public Vector nameResponse(String responseXML) { Reader reader = new BufferedReader(new StringReader(responseXML)); InputSource source = new InputSource(reader); // Use an instance of ourselves as the SAX event handler DefaultHandler handler = new ParseNameResponse(); // Use the default (non-validating) parser SAXParserFactory factory = SAXParserFactory.newInstance(); try { // Parse the input SAXParser saxParser = factory.newSAXParser(); saxParser.parse(source,handler); } catch (Exception e) { e.printStackTrace(); } return namesList; } as you can see the Vector namesList is an instance variable, and being intialized as the time of declaration, but as I add contents to the vector, in the characters method, which the SAX parser calls, on the time of parsing, the instance Vector namesList doesn't get updated, so when I return the vector, from the above nameResponse method the size of the vector is 0. the following is the characters method, in which I add to the namesList Vector. public void characters(char buf[], int offset, int len) { try { String s = new String(buf, offset, len); if (( !s.trim().equals("")) ) { namesList.add(s); } } catch (Exception e) { e.printStackTrace(); } } as I println the size of the vector in the characters method its increasing, means that the objects are being added to the Vector, but when I get back in the initial nameResponse() method after the parsing is completed, the size of the vector is 0 again. Moreover if initialize the vector in the nameResponse method, the characters method shows a nullPointerException, as if the vector hasn't been initialized. any help regarding this specially the second problem. Regards, Babar Abbas.
  2. 1: Simply don't write to a FileOutputStream, but to an "in-memory" stream (a ByteArrayOutputStream wrapped in a BufferedOutputStream (optional) would work). 2. Your design is messy. Your nameResponse method in ParseNameResponse instantiates a new ParseNameResponse instance, which parses the data and adds the tokens to the inner ParseNameResponse's Vector. However, you return the first ParseNameResponse's Vector, which of course is untouched. You will have to do some rewriting to correct this. /Niklas