SAX parsing and loops problem

Hi!
I currently have an XML file which looks like this:
<jel>
<admin creation="Fri Nov 09 17:14:55 GMT 2007" xsdversion="1.0.0" version="1.0.0"/>
&#8722;
     <jelclass superclass="Object" visibility="public" package="" superclassfulltype="java.lang.Object" fulltype="Player" type="Player">
&#8722;
     <implements>
<interface fulltype="java.awt.event.ActionListener" type="ActionListener"/>
<interface fulltype="java.awt.event.KeyListener" type="KeyListener"/>
</implements>
&#8722;
     <methods>
&#8722;
     <constructor visibility="public" name="Player">
&#8722;
     <params>
<param name="newProtocol" fulltype="NewProtocol" type="NewProtocol"/>
<param name="x" fulltype="int" type="int"/>
<param name="y" fulltype="int" type="int"/>
</params>
</constructor>
&#8722;
     <method visibility="public" name="actionPerformed" fulltype="void" type="void">
&#8722;
     <params>
<param name="e" fulltype="java.awt.event.ActionEvent" type="ActionEvent"/>
</params>
</method>
&#8722;
     <method visibility="public" name="keyPressed" fulltype="void" type="void">
&#8722;
     <params>
<param name="e" fulltype="java.awt.event.KeyEvent" type="KeyEvent"/>
</params>
</method>
&#8722;
     <method visibility="public" name="keyReleased" fulltype="void" type="void">
&#8722;
     <params>
<param name="e" fulltype="java.awt.event.KeyEvent" type="KeyEvent"/>
</params>
</method>
&#8722;
     <method visibility="public" name="keyTyped" fulltype="void" type="void">
&#8722;
     <params>
<param name="e" fulltype="java.awt.event.KeyEvent" type="KeyEvent"/>
</params>
</method>
<method visibility="public" name="getX" fulltype="int" type="int"/>
&#8722;
     <method visibility="public" name="setX" fulltype="void" type="void">
&#8722;
     <params>
<param name="x" fulltype="int" type="int"/>
</params>
</method>
<method visibility="public" name="getY" fulltype="int" type="int"/>
&#8722;
     <method visibility="public" name="setY" fulltype="void" type="void">
&#8722;
     <params>
<param name="y" fulltype="int" type="int"/>
</params>
</method>
</methods>
</jelclass>And I have SAX parsing code that looks like this:
public class SaxParser{
      private HashSet <String>packageSet = new HashSet<String>();
      private ArrayList <String> classList = new ArrayList<String>();
      private ArrayList <String> packageList = new ArrayList<String>();
      private ArrayList <String> methodList = new ArrayList<String>();
      private Object[] packageNames;
      private HashMap <String, ArrayList> h = new HashMap <String, ArrayList>();
      public SaxParser()throws Exception{
          String fname = "eclipse/jel.xml";
         DefaultHandler handler = new DefaultHandler()
             private int numberOfClasses = 0;
         public void startElement(String namespaceURI,String localName, String qname, Attributes attrs)
              if(qname.equals("jelclass")) {
                   numberOfClasses ++;
              for(int i = 0; i< attrs.getLength();i++){
                    if(attrs.getQName(i).equals("type")){
                         classList.add(attrs.getValue(i));
                         if(attrs.getQName(i).equals("package")){
                              packageList.add(attrs.getValue(i));
                              packageSet.add(attrs.getValue(i));
              for(int i = 0; i< attrs.getLength();i++){
                   for(int j = 0; j < classList.size(); j++){
          if(attrs.getQName(i).equals("type") && attrs.getValue(i).equals(classList.get(j))){
              if(qname.equals("method")){
                    if(attrs.getQName(i).equals("name")){
                                h.put(classList.get(i), methodList.add(attrs.getValue(i));
               packageNames = new String[packageSet.size()];
              packageNames = packageSet.toArray();
         public void endElement(String namespaceURI,String localName, String qname){}};
        SAXParserFactory factory = SAXParserFactory.newInstance();
        SAXParser saxParser = factory.newSAXParser();
        saxParser.parse(new File(fname), handler);
     public int getPackageNumber(){
          return packageSet.size();
     public Object[] getPackageNames(){
          return packageNames;
     public ArrayList getPackageList(){
          return packageList;
     public ArrayList getClassList(){
          return classList;
     public ArrayList getMethodList(){
          return methodList;
      public static void main(String[] args)throws Exception{
           new SaxParser();
}I am currently pulling out the package names, pulling out the classnames and then mapping these in a separate class - this works because the class and package names are declared in the same line, so if a package name appears in the package list 7 times, i know this package has 7 classes, and therefore i count the first 7 classes out of an array of all the classes and know that these are the right 7 for that package. However, the methods are a bit different:
What I would like to do is to: for every class make a hashmap which maps the class name onto an arraylist of the methods, but i think i'm getting confused with my for loops. Or even just keep a tally of how many methods each class has, then I can work it out as i did with the packages -> classes.
Does anyone know where im going wrong, or have any ideas at all?
Thank you for your time,
beccy
:)

I don't know if stacks are specifically mentioned in any SAX documentation.
Basically, SAX sends you a stream of XML elements (open and close tags, characters, etc.), but it doesn't know anything about the underlying XML structure. You have to add that part (usually -- sometimes when writing a SAX application, you don't really care about the XML structure). XML structure is a tree.
If you've ever written a recursive function that spans a tree, you'll have an idea what to do. You can use a stack to keep track of where you are in the tree. For example, if you open tag A, then you're "in" the A element for subsequent content in that document; if you then open tag B, you're in the B element; but when you close the B tag, you need the stack to tell you that now you're back in the A element.
You may not need stacks, but it's likely. Find a good tutorial about SAX that mentions stacks and you'll be fine.
Edited by: paulcw on Nov 14, 2007 4:09 PM

Similar Messages

  • SAX Parser and special character problem

    Hi,
    Could anyone help with the following problem?
    Background:
    1. Using a SAX Parser (Oracle Implementation) to read XML from a CLOB, convert this XML to another format to be inserted in the database.
    2. Due to performance issues we parse the input stream from the CLOB.
    3. For same reason, we are not using XSL.
    This is the problem we face:
    1. Values of some of the tags in the XML have special characters (Ex: &, <, >).
    2. While using the SAX Parser, the element handler function for the SAX Parser is called by the frame work with the value of these tags broken up with each of these characters being treated as a tag delimiter.
    Ex: <Description>SomeText_A & SomeText_B</Description>
    is treated as SomeText_A in first call to the handler; SomeText_B in the second call.
    The handler function does not get to see the "&" character.
    Thus, the final conversion is
    Say, <Description> is to be converted to <FreeText>
    we, get <FreeText>SomeText_A</FreeText>
    <FreeText>SomeText_B</FreeText>
    We tried using &; but it then breaks it up into SomeText_A, & and SomeText_B.
    How can we get the whole value for the <Description> tag in the characters() function in the SAXParser so that we can convert it to <FreeText>SomeText_A & SomeText_B</FreeText>.
    Thanks in advance..
    Chirdeep.

    We already tried that..looks like the line where I mentioned that it converted the entity referece characters to an ampersand..
    "We tried using <entity reference for &> but it then breaks it up into SomeText_A, & and SomeText_B."
    null

  • SAX Parser XML Validation Problems

    Hi,
    I’m having problems getting an xml document to validate within Weblogic 8.1. I am trying to parse a document that references both a dtd and xsd. Both the schema and dtd reference need to be substituted so they use local paths. I specify the schema the parser should use and have created an entityResolver to change the dtd reference.
    When this runs as a standalone app from eclipse the file parses and validates without a problem. When deployed to the app server the process seems to be unable read the contents of the dtd. Its not that it cannot find the file (no FileNotFoundException is thrown but this can be created if I delete the dtd) rather it seems to find no declared elements.
    Initial thought was that the code didn’t have access to read the dtd from its location on disk, to check I moved the dtd to within the deployed war and reference as a resource. The problem still persists.
    Code Snippet:
    boolean isValid = false;
    try {
         // Create and configure factory
    SAXParserFactory factory = SAXParserFactoryImpl.newInstance();
    factory.setValidating(true);
    factory.setNamespaceAware(true);
    // To be notified of validation errors in the XML document,
    // add a custom error handler to the document builder
    PIMSFeedFileValidationHandler handler
    = new PIMSFeedFileValidationHandler();
         // Create and Configure Parser
    SAXParser parser = factory.newSAXParser();
    parser.setProperty(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA);
    parser.setProperty(NAMESPACE_PROPERTY_KEY, getSchemaFilePath());
         // Set reader with entityResolver for dtd
    XMLReader xmlReader = parser.getXMLReader();
    xmlReader.setEntityResolver(new SAXEntityResolver(this.dtdPath));
    // convert file to URL, as it is a remote file
    URL url = super.getFile().toURL();
    // Open an input stream and parse
    InputStream is = url.openStream();
    xmlReader.setErrorHandler(handler);
    xmlReader.parse(new InputSource(is));
    is.close();
    // get the result of parsing the document by checking the
    // errorhandler's isValid property
    isValid = handler.isValid();
    if (!isValid) {
    LOGGER.warn(handler.getMessage());
    LOGGER.debug("XML file is valid XML? " + isValid);
    } catch (ParserConfigurationException e) {
    LOGGER.error("Error parsing file", e);
    } catch (SAXException e) {
    LOGGER.error("Error parsing file", e);
    } catch (IOException e) {
    throw new FeedException(e);
    return isValid;
    See stack trace below for a little more info.
    2005-01-28 10:24:09,217 [DEBUG] [file] - Attempting validation of file 'cw501205.wa1.xml' with schema at 'C:/pims-feeds/hansard/schema/hansard-v1-9.xsd'
    2005-01-28 10:24:09,217 [DEBUG] [file] - Entity Resolver is using DTD path file:C:/Vignette/runtime_services/8.1/install/common/nodemanager/
    VgnVCMServer/stage/pims-hansard/pims-hansard.war/WEB-INF/classes/com/morse/pims/cms/feed/sax/ISO-Entities.dtd
    2005-01-28 10:24:09,227 [DEBUG] [file] - Creating InputSource at: file:C:/Vignette/runtime_services/8.1/install/common/nodemanager/VgnVCMServer/stage/pims-hansard/pims-hansard.war/WEB-INF/classes/com/morse/pims/cms/feed/sax/ISO-Entities.dtd
    2005-01-28 10:24:09,718 [WARN ] [file] - org.xml.sax.SAXParseException: Element type "Hansard" must be declared.
    org.xml.sax.SAXParseException: Element type "Session" must be declared.
    org.xml.sax.SAXParseException: Element type "DailyRecord" must be declared.
    org.xml.sax.SAXParseException: Element type "Volume" must be declared.
    org.xml.sax.SAXParseException: Element type "Written" must be declared.
    org.xml.sax.SAXParseException: Element type "WrittenHeading" must be declared.
    org.xml.sax.SAXParseException: Element type "Introduction" must be declared.
    … continues for all the elements in the doc
    2005-01-28 10:24:10,519 [DEBUG] [file] - XML file is valid XML? false
    2005-01-28 10:24:10,519 [WARN ] [file] - Daily Part file 'cw501205.wa1.xml' was not valid XML and was not processed.
    Has anybody seen this behavior before with weblogic and if so how have you resolved the issue.
    Thanks in Advance
    Adam

    Hi David,
    I have checked the ejb-jar.xml file and there is no duplicate values in it and the other things is that the same application is been deployed on OAS 10G and websphere and its working fine. In the forum someone has replied to a similar problem that there is bug in Weblogic 10.3 and its CR no 376292. I am not sure about it, does anyone any information about it.
    Thanks and Regards
    Deepak Dani

  • SAX-parser and mapping on the XI

    Helllo everybody,
    I'm trying to map an xml-document using the SAX-parser.
    I'm reading the data using an impustream. the problem is, while testing on the XI, the following message comes :
    Creating Java mapping xmlDataExchangeSAPSample/XMLValidation
    Loaded class xmlDataExchangeSAPSample.XMLValidation
    Loaded class xmlDataExchangeSAPSample.myErrorHandler
    Call method execute of the application Java mapping xmlDataExchangeSAPSample.XMLValidation
    START APPLICATION TRACE ***
    xxx implementierende Klasse Parserscom.sap.engine.lib.jaxp.SAXParserFactoryImpl
    erstelltes Dokument aus in EDIFACTINTERCHANGE
    Beginn Parsenjava.io.ByteArrayInputStream@1aa342a3
    SAXException when parsing Generic Exception:
    com.sap.engine.lib.xml.util.NestedException -> com.sap.engine.lib.xml.parser.ParserException -> java.io.IOException: Parsing an empty source. Root element expected!
    END APPLICATION TRACE ***
    Java mapping xmlDataExchangeSAPSample/XMLValidation completed. (execute() of xmlDataExchangeSAPSample.XMLValidation
    Ausführung war erfolgreich.
    10:18:14 Testende
    the the Document ist generated :
    "...erstelltes Dokument aus in EDIFACTINTERCHANGE.."
    but the parser find an empty source.
    do you have an idea what could be happening here?
    Kind regards

    Hi,
      <<
    xxx implementierende Klasse Parserscom.sap.engine.lib.jaxp.SAXParserFactoryImpl
    erstelltes Dokument aus in EDIFACTINTERCHANGE
    Beginn Parsenjava.io.ByteArrayInputStream@1aa342a3
    SAXException when parsing Generic Exception:
    com.sap.engine.lib.xml.util.NestedException -> com.sap.engine.lib.xml.parser.ParserException -> java.io.IOException: Parsing an empty source. Root element expected!
    >>
    This seems that u r trying parse a file rather than valid XML document..
    Usually you will notice this problem when u r trying to parse a payload which is in txt format usually when u r using File Adapter message protocol as "FILE" instead of "FCC".
    Usually SAX is an API Desinged to parse Valid XML Documents only.
    If you want to do manipulations on NON XML data better to use Java.io.InputStream & OutputStream.
    Regards,
    Rao.Mallikarjuna

  • SAX parser and EntityResolver

    I am using the sample SAXSample.java that comes as part of the XML parser download to parse an XML file that contains references to external entities - for example <!ENTITY E23678 SYSTEM "http://pilot/:13365">
    However the SAX parser never appears to call either the EntityResolver or DTDHandler handlers even though they are set in main.
    Has anyone else experienced this or have a missed something out?
    Any help appreciated.

    public class YourParser extends DefaultHandler implements Runnable
    in yor run method
    saxParser.parse(fileToBeParsed, this); provide implementation to the methods y want in YourParser  class
    //saxParser is an object of javax.xml.parsers.SAXParser

  • SAX Parser Global Variable problem

    Can someone tell me what i am doing wrong.
    i have a javabean called querybean that i store cdata from an xml file. i also have a map that i want to store this querybean in.
    when i debug this, i can see the map being populated in my end element event call, but when i return the map, there is nothing in it.
    I'm not really sure why this is. is the calling of the parser events run on a differnt thread or something.
    here is my code
    public class XmlParsing extends DefaultHandler implements LexicalHandler{
         String reportId = null;
         boolean cdataSection = false;
         StringBuffer cdataString = new StringBuffer();
         Map queryMap = new HashMap();
         QueryBean queryBean = new QueryBean();
         public static final String LEXICAL_SAX_PROPERTY =
         "http://xml.org/sax/properties/lexical-handler";
         public Map XmlPassThrough(File file)
              DefaultHandler handler = new XmlParsing();
              SAXParserFactory factory = SAXParserFactory.newInstance();
              try
              SAXParser saxParser = factory.newSAXParser();
              saxParser.setProperty("http://xml.org/sax/properties/lexical-handler",handler);
              saxParser.parse(file,handler);
              catch(Exception e)
                   e.printStackTrace();
              return this.queryMap;
         //////////Setters and Getters////////////////////////////
         public String getReportId() {
              return reportId;
         public void setReportId(String reportId) {
              this.reportId = reportId;
         public boolean isCdataSection() {
              return cdataSection;
         public void setCdataSection(boolean cdataSection) {
              this.cdataSection = cdataSection;
         public StringBuffer getCdataString() {
              return cdataString;
         public void setCdataString(StringBuffer cdataString) {
              this.cdataString = cdataString;
         public Map getQueryMap() {
              return queryMap;
         public void setQueryMap(Map queryMap) {
              this.queryMap = queryMap;
         /* Handler Methods*/
         public void startDocument() throws SAXException{
              System.out.println("Start of Document");
         public void endDocument() throws SAXException{
              System.out.println("End of Document");
         public void startElement(String namespaceURI,
                                       String lName,
                                       String qName,
                                       Attributes attrs)
         throws SAXException
              String eName = lName;
              if("".equals(eName)) eName = qName;
              if(qName.equals("sql"))
                             queryBean.setReportID(attrs.getValue("report_id"));
                             queryBean.setReportType(attrs.getValue("report_type"));
                             if(attrs.getValue("report_start_date").equals("true"))
                             queryBean.setReport_start_date(true);
                             else
                                  queryBean.setReport_start_date(false);
         public void endElement(String namespaceURI,
    String sName, // simple name
    String qName // qualified name
    throws SAXException
              if(qName.equals("select"))
                   queryBean.setSelect(this.getCdataString());
              else if(qName.equals("from"))
                   queryBean.setFrom(this.getCdataString());
              else if(qName.equals("where"))
                   queryBean.setWhere(this.getCdataString());
              else if(qName.equals("group"))
                   queryBean.setGroup(this.getCdataString());
              else if(qName.equals("order"))
                   queryBean.setOrder(this.getCdataString());
              else if(qName.equals("sql"))
                   this.queryMap.put(queryBean.getReportID(),queryBean);
                   this.setQueryMap(queryMap);
              this.cdataString.setLength(0);
         public void characters(char buf[], int offset, int len)
    throws SAXException
              if(this.isCdataSection())
                   String str = new String(buf,offset,len);
                   this.cdataString.append(str);
         /* LexicalHandler Methods*/
         public void endCDATA() throws SAXException {
              // TODO Auto-generated method stub
              System.out.println(this.cdataString.toString());
              System.out.println("end of CDATASECTION");
              this.setCdataSection(false);
         public void endDTD() throws SAXException {
              // TODO Auto-generated method stub
         public void startCDATA() throws SAXException {
              // TODO Auto-generated method stub
              System.out.println("Start of CDATASECTION");
              this.setCdataSection(true);
         public void comment(char[] ch, int start, int length) throws SAXException {
              // TODO Auto-generated method stub
         public void endEntity(String name) throws SAXException {
              // TODO Auto-generated method stub
         public void startEntity(String name) throws SAXException {
              // TODO Auto-generated method stub
         public void startDTD(String name, String publicId, String systemId) throws SAXException {
              // TODO Auto-generated method stub
         }

    Well, despite all your copious use of "this" you actually have two instances of your class. You create one, then in its XmlPassThrough method you create a second one to be the handler for the first one. The second one is where you accumulate all your data, and then you return the empty data from the first one.
    So remove this line:DefaultHandler handler = new XmlParsing();and replace all references to the "handler" variable by "this". That way your XmlParsing object acts as its own handler and accumulates data in its own fields.

  • Need help with input, parsing, and loop in one program

    I am doing an assignment that is supposed to:
    # ask the user for a URL
    # For the entered URL, read all the HTML text from the page and extract all links (other URLs) and image names. These should be printed to the console window.
    # Reprompt for a URL until the user presses the cancel button.
    # Define at least one helper method that serves a practical purpose that your main method will use. Note that your method(s) should serve a useful purpose, and it should make sense that they are separated out from the main method.
    So far, I figured out how to ask if the user would like to play again, though I can't make it loop to play again. The "NO_OPTION" works fine and exits out.
    I cannot figure out at all how to ask for the URL and then use that URL to try to parse the HTML to find the links and pictures.
    for the loop, is it:
    do{
    ...//all the stuff//
    }while (option == JOptionPane.YES_OPTION) ?(I think I have to parse, looking for "img src" and "a href", anyway)
    The biggest thing I'm getting hung up about is where to start. All it'll do is ask for the URL, say there is an error, and ask if I want to do it again. Don't know how to make it loop again. Like I said, I think it's a do while loop but am not completely sure where it goes and how to have it work on the entire thing with message dialoge boxes
    To ask for the input, I was trying to make the dialoge box a string so the string would be displayed and have the links extracted
    String linkString=   
              JOptionPane.showInputDialog("Please enter a URL:");...but it obviously doesn't work like that...
    Here is the whole mess so far...I don't know what my question is because I know what I want, just not the terms to ask. help?
    import java.io.BufferedReader;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.net.URL;
    import java.net.URLConnection;
    import javax.swing.JOptionPane;
    public class WebPageExaminer
         public static void main(String[] args)
              String linkString=   
              JOptionPane.showInputDialog("Please enter a URL:");
        String link = null;
        URL url;
        URLConnection urlC;
        InputStream inStream;
        InputStreamReader inStreamReader;
        BufferedReader reader;
        try
        url = new URL(link);
        urlC = url.openConnection();
        inStream = urlC.getInputStream();
        inStreamReader = new InputStreamReader(inStream);
        reader = new BufferedReader(inStreamReader);
        String inputLine = reader.readLine();
        while (inputLine != null)
          System.out.println(inputLine);
          inputLine = reader.readLine();
        catch(Exception e)
          JOptionPane.showMessageDialog(null, "Error reading from file");
        } int answer = JOptionPane.showConfirmDialog(null, "Examine Another URL?", "Click Yes or NO:", JOptionPane.YES_NO_OPTION);
        if (answer == JOptionPane.NO_OPTION)
             System.out.println("Goodbye");
             System.exit(0);
              if (answer == JOptionPane.YES_OPTION)
                  System.out.println("OK!");
    }Edited by: digital.tradecraft on Mar 14, 2009 1:27 PM

    You posted the questions 20 minutes ago? Why are you bumping it. People answer questions when they know the answer.
    I tend to ignore people who expect an immediate answer.

  • Problem in parsing an XML using SAX parser

    Hai All,
    I have got a problem in parsing an XML using SAX parser.
    I have an XML (sample below) which need to be parsed
    <line-items>
    <item num="1">
         <part-number>PN1234</part-number>
         <quantity uom="ea">10</quantity>
         <lpn>LPN1060</lpn>
         <reference num="1">Line ref 1</reference>
         <reference num="2">Line ref 2</reference>
         <reference num="3">Line ref 3</reference>
    </item>
    <item num="2">
         <part-number>PN1527</part-number>
         <quantity uom="lbs">5</quantity>
         <lpn>LPN2152</lpn>
         <reference num="1">Line ref 1</reference>
         <reference num="2">Line ref 2</reference>
         <reference num="3">Line ref 3</reference>
    </item>
    <item num="n">
    </item>
    </line-items>
    There can be any number of items( 1 to n). I need to parse these
    item values using SAX parser and invoke a stored procedure for
    each item with its
    values(partnumber,qty,lpn,refnum1,refnum2,refnum3).
    Suppose if there are 100 items, i need to invoke the stored
    procedure sp1() 100 times for each item.
    I need to invoke the stored procedure in endDocument() method of
    SAX event handler and not in endelement() method.
    What is the best way to store those values and invoke the stored
    procedure in enddocument() method.
    Any help would br greatly appreciated.
    Thanks in advance
    Pooja.

    VO or ValueObject is a trendy new name for Beans.
    So just create an item class with variables for each of the sub elements.
    <item>
    <part-number>PN1234</part-number>
    <quantity uom="ea">10</quantity>
    <lpn>LPN1060</lpn>
    <reference num="1">Line ref 1</reference>
    <reference num="2">Line ref 2</reference>
    <reference num="3">Line ref 3</reference>
    </item>
    public class ItemVO
    String partNumber;
    int quantity;
    String quantityType;
    String lpn;
    List references = new ArrayList();
    * @return Returns the lpn.
    public String getLpn()
    return this.lpn;
    * @param lpn The lpn to set.
    public void setLpn(String lpn)
    this.lpn = lpn;
    * @return Returns the partNumber.
    public String getPartNumber()
    return this.partNumber;
    * @param partNumber The partNumber to set.
    public void setPartNumber(String partNumber)
    this.partNumber = partNumber;
    * @return Returns the quantity.
    public int getQuantity()
    return this.quantity;
    * @param quantity The quantity to set.
    public void setQuantity(int quantity)
    this.quantity = quantity;
    * @return Returns the quantityType.
    public String getQuantityType()
    return this.quantityType;
    * @param quantityType The quantityType to set.
    public void setQuantityType(String quantityType)
    this.quantityType = quantityType;
    * @return Returns the references.
    public List getReferences()
    return this.references;
    * @param references The references to set.
    public void setReferences(List references)
    this.references = references;

  • How to deal with empty tags in a SAX Parser

    Hi,
    I hope someone can help me with the problem I am having!
    Basically, I have written an xml-editor application. When an XML file is selected, I parse the file with a SAX parser and save the start and end locations of all the tags and character data. This enables me to display the xml file with the tags all nicely formatted with pretty colours. Truly it is a Joy To Behold. However, I have a problem with tags in this form:
    <package name="boo"/>
    because the SAX parser treats them like this:
    <package name = boo>
    </package>
    for various complex reasons the latter is unaccetable so my question is: Is there some fiendishly clever method to detect tags of this type as they occur, so that I can treat them accordingly?
    Thanks,
    Chris

    I have spent some time on googling for code doing this, but found nothing better, than I had to write in by myself.
    So, it would be something like this. Enjoy :)
    package comd;
    import org.xml.sax.helpers.DefaultHandler;
    import org.xml.sax.SAXException;
    import org.xml.sax.Attributes;
    import java.util.Stack;
    import java.util.Enumeration;
    public class EmptyTagsHandler extends DefaultHandler {
         private StringBuilder xmlBuilder;
         private Stack<XmlElement> elementStack;
         private String processedXml;
         private class XmlElement{
              private String name;
              private boolean isEmpty = true;
              public XmlElement(String name) {
                   this.name = name;
              public void setNotEmpty(){
                   isEmpty = false;
         public EmptyTagsHandler(){
              xmlBuilder = new StringBuilder();
              elementStack = new Stack();
         private String getElementXPath(){
              StringBuilder builder = new StringBuilder();
              for (Enumeration en=elementStack.elements();en.hasMoreElements();){
                   builder.append(en.nextElement());
                   builder.append("/");
              return builder.toString();
         public String getXml(){
              return processedXml;
         public void startDocument() throws SAXException {
              xmlBuilder = new StringBuilder();
              elementStack.clear();
              processedXml = null;
         public void endDocument() throws SAXException {
              processedXml = xmlBuilder.toString();
         public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
              if (!elementStack.empty()) {
                   XmlElement elem = elementStack.peek();
                   elem.setNotEmpty();
              xmlBuilder.append("<");
              xmlBuilder.append(qName);
              for (int i=0; i<attributes.getLength();i++){
                   xmlBuilder.append(" ");
                   xmlBuilder.append(attributes.getQName(i));
                   xmlBuilder.append("=");
                   xmlBuilder.append(attributes.getValue(i));
              xmlBuilder.append(">");
              elementStack.push(new XmlElement(qName));
         public void endElement(String uri, String localName, String qName) throws SAXException {
              XmlElement elem = elementStack.peek();
              if (elem.isEmpty) {
                   xmlBuilder.insert(xmlBuilder.length()-1, "/");
              } else {
                   xmlBuilder.append("</");
                   xmlBuilder.append(qName);
                   xmlBuilder.append(">");
              elementStack.pop();
         public void characters(char ch[], int start, int length) throws SAXException {
              if (!elementStack.empty()) {
                   XmlElement elem = elementStack.peek();
                   elem.setNotEmpty();
              String str = new String(ch, start, length);
              xmlBuilder.append(str);
         public void ignorableWhitespace(char ch[], int start, int length) throws SAXException {
              String str = new String(ch, start, length);
              xmlBuilder.append(str);
    }

  • XML - SAX Parsing Question

    Hi,
    I am parsing XML using SAX parser and fill the values into the HashTable ( like Key value pair ).. so i can get the vaues for a particular key using hash get function.
    For the following XML. There are 2 "subscriberNumber" attribute, one is under "sn:Subscriber" and the another is under "sn:SubscriberChange".
    I can able to put this values in hash table and when i print the Hash table it is printing as sn:subscriberNumber=[1234567890, 1234567890] .. But how will i know which one is from "sn:Subscriber" and which is from "sn:SubscriberChange"
    This is the XML :
    <sn:SubscriberNotification>
    <sn:notificationSubType>1120</sn:notificationSubType>
    <sn:Subscriber>
         <cng:PaymentType>PostPaid</cng:PaymentType>
         <sn:subscriberNumber>1234567890</sn:subscriberNumber>
    </sn:Subscriber>
    <sn:SubscriberChange>
         <sn:subscriberNumber>1234567890</sn:subscriberNumber>
    </sn:SubscriberChange>
    </sn:SubscriberNotification>
    Any suggestion and pointers are really helpful
    Thanks,
    -Raj..

    Try something like this:
    import java.util.Stack;
    import org.xml.sax.Attributes;
    import org.xml.sax.SAXException;
    import org.xml.sax.helpers.DefaultHandler;
    class MyHandler extends DefaultHandler {
        Stack openTags = new Stack();
        public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
            if (qName.equals("sn:subscriberNumber")) {
                String parentTag = (String)openTags.peek();
                System.out.println("Parent tag of this <sn:subscriberNumber> is : <" + parentTag + ">");
            openTags.push(qName);
        public void endElement(String uri, String localName, String qName) throws SAXException {
            openTags.pop();
    }Regards

  • Problem Using Sax parser with Eclipse 3.0 and command line

    Hi,
    I am parsing a xml file with sax. When I am running my programm in the command line everthing is ok and I get the right results from parsing.
    But if I am running the programm in Eclipse 3.0 (the same java code) I get an other result (the wrong results).
    Does anybody know what this can be the reason for. Is Eclipse using an other xml parser and if where I can change the parser?
    It would be very kind if somebody can give me a reason for this strange behaviour.
    Thanks in advance

    I have solved my problem.
    In the command line I used jre 1.4 and in Eclipse I used jre 1.5.
    I think jre 1.5 uses an other xml parser so I got an other result.
    If i use in Eclipse jre1.4 I get the same result as in the command line.

  • Sax parser problem

    hi,
    i am assuming the problem is with sax parser but i cant be sure. I am parsing a xml file (about 1.4MB) with some data in it. the parser i have created reads the xml file correctly for the most part but when at some point the
    "public void characters(char buf[], int offset, int len) throws SAXException"
    function stops working correctly....i.e it doesnt fully read read the data between the "<start>" and "</start>" element. say it reads about 100 id's correctly---for 101 ID it does this. This is just an example. Since, the problem might be with how :
    "public void characters(char buf[], int offset, int len) throws SAXException"
    function is reading the data i was wondering if anybody else had encountered this problem or please let me know if i need to change something in the code: here's a part of the code :
    Bascially i have created three classes to enter data into three mysql tables and as i parse the data i fill up the columns by matching the column header with the tagName.
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    import java.sql.*;
    import java.io.*;
    import java.util.ArrayList;
    import java.lang.Object;
    import org.xml.sax.*;
    import org.xml.sax.helpers.DefaultHandler;
    import java.util.*;
    import javax.xml.parsers.SAXParserFactory;
    import javax.xml.parsers.ParserConfigurationException;
    import javax.xml.parsers.SAXParser;
    public class Echo03 extends DefaultHandler
    StringBuffer textBuffer;
    int issuedValue, prodValue;
    OrdHeader header = new OrdHeader();
    OrdDetail detail = new OrdDetail();
    Member memInfo = new Member();
    //new addition to store the dynamic value of the products
    TestOrdheader prod = new TestOrdheader();
    int counter;
    String tag, newTag;
    SetValue setVal = new SetValue();
    String test;
    public static void main(String argv[])
    if (argv.length != 1) {
    System.err.println("Usage: cmd filename");
    System.exit(1);
    // Use an instance of ourselves as the SAX event handler
    DefaultHandler handler = new Echo03();
    // Use the default (non-validating) parser
    SAXParserFactory factory = SAXParserFactory.newInstance();
    try {
    // Set up output stream
    out = new OutputStreamWriter(System.out, "UTF8");
    // Parse the input
    SAXParser saxParser = factory.newSAXParser();
    saxParser.parse( new File(argv[0]), handler);
    } catch (Throwable t) {
    t.printStackTrace();
    System.exit(0);
    static private Writer out;
    private String indentString = " "; // Amount to indent
    private int indentLevel = 0;
    //===========================================================
    // SAX DocumentHandler methods
    //===========================================================
    public void startDocument()
    throws SAXException
    nl();
    nl();
    emit("START DOCUMENT");
    nl();
    emit("<?xml version='1.0' encoding='UTF-8'?>");
    header.assign();
    public void endDocument()
    throws SAXException
    nl(); emit("END DOCUMENT");
    try {
    nl();
    out.flush();
    } catch (IOException e) {
    throw new SAXException("I/O error", e);
    public void startElement(String namespaceURI,
    String lName, // local name
    String qName, // qualified name
    Attributes attrs)
    throws SAXException
    indentLevel++;
    nl(); //emit("ELEMENT: ");
    String eName = lName; // element name
    if ("".equals(eName)) eName = qName; // namespaceAware = false
    if (qName.equals("Billing")){
    issuedValue = 1;
    }else if (qName.equals("Shipping")){
    issuedValue = 2;
    }else if (qName.equals("ShippingTotal")){
    issuedValue = 3;
    //check to see if "Product" is the name of the element thats coming next
    if (qName.equals("Product")){
    if (issuedValue != 3){
    prodValue = 1;
    prod.addCounter();
    }else{
    prodValue = 0;
    tag = eName;
    if (attrs != null) {
    for (int i = 0; i < attrs.getLength(); i++) {
    String aName = attrs.getLocalName(i); // Attr name
    if ("".equals(aName)) aName = attrs.getQName(i);
    nl();
    emit(" ATTR: ");
    emit(aName);
    emit("\t\"");
    emit(attrs.getValue(i));
    emit("\"");
    if (attrs.getLength() > 0) nl();
    public void endElement(String namespaceURI,
    String sName, // simple name
    String qName // qualified name
    throws SAXException
    nl();
    String eName = sName; // element name
    if ("".equals(eName)){
    eName = qName; // not namespaceAware
    if ("Order".equals(eName)){          
    //enter into database
         databaseEnter();
    textBuffer = null;
    indentLevel--;
    public void characters(char buf[], int offset, int len)
    throws SAXException
    nl();
    try {
    String s = new String(buf, offset, len);
    if (!s.trim().equals("")){
    settag(tag, s);
    s = null;
    }catch (NullPointerException E){
    System.out.println("Null pointer Exception:"+E);
    //===========================================================
    // Utility Methods ...
    //===========================================================
    // Wrap I/O exceptions in SAX exceptions, to
    // suit handler signature requirements
    private void emit(String s)
    throws SAXException
    try {
    out.write(s);
    out.flush();
    } catch (IOException e) {
    throw new SAXException("I/O error", e);
    // Start a new line
    // and indent the next line appropriately
    private void nl()
    throws SAXException
    String lineEnd = System.getProperty("line.separator");
    try {
    out.write(lineEnd);
    for (int i=0; i < indentLevel; i++) out.write(indentString);
    } catch (IOException e) {
    throw new SAXException("I/O error", e);
    ===================================================================
    ///User defined methods
    ===================================================================
    private String strsplit(String splitstr){
    String delimiter = new String("=");
    String[] value = splitstr.split(delimiter);
    value[1] = value[1].replace(':', ' ');
    return value[1];
    public void settag(String tag, String s){         
    String pp_transid = null, pp_respmsg = null,pp_authid = null, pp_avs = null, pp_avszip = null;
    if ((tag.equals("OrderDate")) || (tag.equals("OrderProcessingInfo"))){
    if (tag.equals("OrderDate")){
    StringTokenizer st = new StringTokenizer(s);
    String orddate = st.nextToken();
    String ordtime = st.nextToken();
    header.put("ordDate", orddate);
    header.put("ordTime", ordtime);
    }else if (tag.equals("OrderProcessingInfo")){
    StringTokenizer st1 = new StringTokenizer(s);
    int tokenCount = 1;
    while (tokenCount <= st1.countTokens()){
    switch(tokenCount){
    case 1:
    String extra = st1.nextToken();
    break;
    case 2:
    String Opp_transid = st1.nextToken();
    pp_transid = strsplit(Opp_transid);
    break;
    case 3:
    String Opp_respmsg = st1.nextToken();
    pp_respmsg = strsplit(Opp_respmsg);
    break;
    case 4:
    String Opp_authid = st1.nextToken();
    pp_authid = strsplit(Opp_authid);
    break;
    case 5:
    String Opp_avs = st1.nextToken();
    pp_avs = strsplit(Opp_avs);
    break;
    case 6:
    String Opp_avszip = st1.nextToken();
    pp_avszip = strsplit(Opp_avszip);
    break;
    tokenCount++;
    header.put("pp_transid", pp_transid);
    header.put("pp_respmsg", pp_respmsg);
    header.put("pp_authid", pp_authid);
    header.put("pp_avs", pp_avs);
    header.put("pp_avszip", pp_avszip);
    }else{
    newTag = new String(setVal.set_name(tag, issuedValue));
    header.put(newTag, s);
    //detail.put(newTag, s);
    prod.put(newTag, s);
    memInfo.put(newTag,s);
    //Check to see-- if we should add this product to the database or not
    boolean check = prod.checkValid(newTag, prodValue);
    if (check){
    prod.addValues(s);
    setVal.clearMod();
    ==================================================================
    Here's the error that i get:
    java.util.NoSuchElementException
    at org.apache.crimson.parser.Parser2.parseInternal(Parser2.java:691)
    at org.apache.crimson.parser.Parser2.parse(Parser2.java:337)
    at org.apache.crimson.parser.XMLReaderImpl.parse(XMLReaderImpl.java:448)
    at javax.xml.parsers.SAXParser.parse(SAXParser.java:345)
    at javax.xml.parsers.SAXParser.parse(SAXParser.java:281)
    at Echo03.main(Echo03.java:47)

    I haven't gone through your code but I also had a similar error....and the exception in my was because of an "&" instead of the entity reference & in one of the element values. I use a non-validating parser but if you use a validating one then this might not be the reason for your exception.

  • Problem in using SAX parser.

    Hai All,
    I have got a problem in using SAX parser.
    My XML looks like this:
    <authorizer>
    <first-name>HP</first-name>
    <last-name>Services</last-name>
    <phone>800-22-1984</phone>
    </authorizer>
    <destination>
    <first-name>John</first-name>
    <last-name>Doe</last-name>
    <company>John Doe Enterprises, Inc.</company>
    <department>Manufacturing</department>
    <phone>800-555-1234</phone>
    <address>
    <street-one>1654 Peachtree Str</street-one>
    <street-two>Suite Y</street-two>
    <city>Atlanta</city>
    <province>GA</province>
    <country>US</country>
    <postal-code>30326</postal-code>
    </address>
    </destination>
    my part of SAX parser code is:
    public void startElement (String name, AttributeList attrs)
    throws SAXException
    accumulator.setLength(0);
    public void characters (char buf [], int offset, int len)
    throws SAXException
    accumulator.append(buf, offset, len);
    public void endElement (String name)
    throws SAXException
    if (name.equals("first-name") )
    firstname=accumulator.toString().trim();
    if (name.equals("last-name"))
    lastname=accumulator.toString().trim();
    My problem is that i have to store the values of first-name and last-name.
    but i have that in both
    <authorizer> </authorizer> Tag and
    <destination> </destination>
    I need to retrive authorizer's firstname,lastname and
    destination's firstname and lastname.
    what i mean is i need to store authorizerFirstName,authorizerLastName
    destinationFirstname and destinationLastname.
    Pls let me know how to do that.
    Thanks in advance.
    Pooja.

    hi pooja,
    I think you are using DataHandler for parsing. Its deprecated. try using contentHandler . You can get the value of the element at the beginning. say for example
    <firstname>sdfs</firstname>
    the startElement will be firstname
    the next method that it invokes will be characters method which has the text associated with the element. I am sending a sample code for your problem. try using it .
    boolean m_boolinAuth = false;
    boolean m_boolinDest = false;
    boolean m_bAuthFName = false;
    boolean m_bAuthLName = false;
    public void startElement(String namespaceURI, String elementName, String qName, Attributes atts)
    //does the logic for startElement
    if(qName.equals("Authorization"))
    m_boolinAuth = true;
    m_boolinDest = false;
    else if(qName.equals("Destination"))
    m_boolinDest = true;
    m_boolinAuth = false;
    if(qName.equals("firstname"))
    m_bFirstName = true;
    if(qName.equals("lastname"))
    m_bLastName = true;
    public void characters(char[] ch, int start, int length)
    //does the logic for characters.
    String str = new String(ch,start,length);
    if(m_bFirstName)
    if(m_boolinAuth)
    m_strAuthFirstName =str;
    else if(m_boolinDest)
    m_strDestFirstName = str;
    m_bFirstName = false;
    if(m_bLastName)
    //same as first name case;
    }

  • Problem with sax parser

    Hello..
    I have the following problem. When I parse an xml document with blank spaces and numbers with decimals, its sometimes comes out as one string and sometimes as two, for example "First A" sometimes comes out as "First" and "A" and sometimes as "First A", which is how its stored in the xml file. Same with numbers like 19.20. Im enclosing a little of my code..
    public void characters(char buf[], int offset, int len)
    throws SAXException
    if (textBuffer != null) {
    SaveString = ""+textBuffer;
    if(i>-1)
    numbers = SaveString;
    Whats wrong and how do I fix it.
    Best Regards Dan
    PS I have more code, in data and out data if needed.Ds

    Hello,
    I do not know if this is your problem, yet please find hereafter an excerpt of the SAX API:
    public void characters(char[] ch,
                           int start,
                           int length)
                    throws SAXException
    ... SAX parsers may return all contiguous character data in a single chunk, or they may split it into several chunks;...
    ... Note that some parsers will report whitespace in element content using the ignorableWhitespace method rather than this one (validating parsers must do so)...
    In other words, I am afraid that your issue is the "standard behaviour" of a SAX parser.
    I hope it helps.

  • SAX parser problem in JDK1.5

    I have parse the xml file using SAX in jdk1.5 environment. During the parsing, it missed the some text content.
    for example
    <employeeid>
    <empid>1001</empid>
    <empid>1002</empid>
    </employeeid>
    If i have parse the above xml file using SAX in jdk1.5 environment. The output is
    1001
    100
    during the parsing , SAX parser misses digit of 2.
    if i have parse the above xml file using SAX in jdk1.4 environment , it is working fine.
    what is the problem in jdk1.5
    please help
    bala

    What I expect the problem to be was discussed recently in a topic titled "SAX Parser Problems" that was started on March 14 at 6:59 AM by JackoBS.
    Read that and see if it fixes your problem. If so, it is not a JDK1.5 problem, but a user error.
    Dave Patterson

Maybe you are looking for