views:

131

answers:

2

Hi all,

I'm trying to parse that document with SAX:

<scxml version="1.0" initialstate="start" name="calc"> 
  <datamodel> 
      <data id="expr" expr="0" /> 
      <data id="res" expr="0" /> 
  </datamodel> 
  <state id="start"> 
      <transition event="OPER" target="opEntered" /> 
      <transition event="DIGIT" target="operand" /> 
  </state> 
  <state id="operand"> 
      <transition event="OPER" target="opEntered" /> 
      <transition event="DIGIT" /> 
  </state> 
</scxml>

I read all the attributes well, except "initialstate" and "name"... I get the attributes with the startElement handler, but the size of the attribute list for scxml is zero. Why? How I can overcome that problem?

Edit:

public void startElement(String uri, String localName, String qName, Attributes attributes){
  System.out.println(attributes.getValue("initialstate"));
  System.out.println(attributes.getValue("name")); 
}

that, when parsing the first tag, doesn't work (prints "null" two times). In fact,

attributes.getLength();

evaluates to zero.

Thanks

+1  A: 

Attributes.getValue() isn't as simple as it look. The javadoc says:

Look up an attribute's value by XML qualified (prefixed) name.

So passing in just "initialstate" might not work if there are any namespace complications, since "initialstate" is not technically a qualified name.

I suggest having a play with the other methods on the Attributes class, such as getValue(int), you might have more succes with those.


edit: Another possibility is that this invocation of startElement isn't referring to the element you think it is. Have you verified that the localName argument is indeed scxml, and not something else?

skaffman
The problem is that the length of the attributes list is zero for the first tag...
akappa
yes, the localName is scxml.
akappa
+2  A: 

I've got a full example working from there and adapted it for your file:

public class SaxParserMain {

    /**
     * @param args
     * @throws SAXException
     * @throws ParserConfigurationException
     * @throws IOException
     */
    public static void main(String[] args) throws ParserConfigurationException, SAXException,
            IOException {
        SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
        CustomHandler handler = new CustomHandler();
        parser.parse(new File("file/scxml.xml"), handler);
    }
}

and

public class CustomHandler extends DefaultHandler {

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes)
            throws SAXException {
        System.out.println();
        System.out.print("<" + qName + "");
        if (attributes.getLength() == 0) {
            System.out.print(">");
        } else {
            System.out.print(" ");
            for (int index = 0; index < attributes.getLength(); index++) {
                System.out.print(attributes.getLocalName(index) + " => "
                        + attributes.getValue(index));
            }
            System.out.print(">");
        }
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        System.out.print("\n</" + qName + ">");
    }
}

The output is:

<scxml version => 1.0initialstate => startname => calc>
<datamodel>
<data id => exprexpr => 0>
</data>
<data id => resexpr => 0>
</data>
</datamodel>
<state id => start>
<transition event => OPERtarget => opEntered>
</transition>
<transition event => DIGITtarget => operand>
</transition>
</state>
<state id => operand>
<transition event => OPERtarget => opEntered>
</transition>
<transition event => DIGIT>
</transition>
</state>
</scxml>
rochb
Uh, thanks, problem solved.The problem is that sax uses always the same attributes instance, filling it everytime it raises an event. I've assumed that it was always a /different/ instance. Sigh! :)
akappa