Search code examples
javaxmlparsingstax

Parsing an XML in Java using STax


This, even to me, seems like a silly question but then is one of those to which i cant find an answer.

Im trying to parse an XML using STax in Java and the XMl im trying to parse looks like this --

<?xml version="1.0" encoding="UTF-8"?>
<Macros>
    <MacroDefinition>
            <MacroName>
                <string>Macro1</string>
            </MacroName>
    </MacroDefinition>
</Macros>

Now i have a Macro class as follows --

 public class Macro {
    private String name; 

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    }

I also have a parser class from where i try to convert the XML into an object of the 'Macro' class. The parser class snippet is as follows --

public class StaxParser {
    static final String MACRODEFINITION = "MacroDefinition";
    static final String MACRONAME = "MacroName";
    static final String STRING = "string";

    @SuppressWarnings({ "unchecked", "null" })
    public List<Item> readMacro(String configFile) {
        List<Macro> macroList = new ArrayList<Macro>();
        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
            Macro macro = null;

            while (eventReader.hasNext()) {
                XMLEvent event = eventReader.nextEvent();

                if (event.isStartElement()) {
                    StartElement startElement = event.asStartElement();
                    if (startElement.getName().getLocalPart() == (MACRODEFINITION)) {
                        macro = new Macro();

                    }

                    if (event.isStartElement()) {
                        if (event.asStartElement().getName().getLocalPart()
                                .equals(MACRONAME)) {
                            Iterator<Attribute> attributes = event
                                    .asStartElement().getAttributes();
                            while (attributes.hasNext()) {
                                Attribute attribute = attributes.next();
                                if (attribute.getName().toString()
                                        .equals(STRING)) {
                                    macro.setMacroName(event.asCharacters()
                                            .getData());
                                }
                            }
                            event = eventReader.nextEvent();
                            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() == (MACRODEFINITION)) {
                        macroList.add(macro);
                    }
                }

            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (XMLStreamException e) {
            e.printStackTrace();
        }
        return macroList;
    }

}

The problem im facing is that the parser is not able to read the child nodes of 'MacroName'. Im thinking getAttributes is what is causing it not to work but have no clue of what method i should be calling to get the child nodes of any particular node.
Any help with this would be greatly appreciated.
Thanks
p1nG


Solution

  • First notice that Macro1 is not XML attribute, so event attributes will be empty. Code after changes (I have only shown lines of code that may be of interest):

      if (event.isStartElement()
         && event.asStartElement().getName().getLocalPart().equals(STRING)) {
              if (macro == null) {
                   macro = new Macro();
              }
               macro.setName(eventReader.getElementText());
      }
    

    A few tips: never ever compare strings using == use equals method. If you need full working example I could post my solution, but it is bit more complicated.