0

I just don't want to reinvent the wheel if not necessary so I'll ask you the following, what is the easiest ways to parse the following into a Java date using a saxparser extension?

<start-date>
   <year>2012</year>
   <month>04</month>
   <day>10</day>
</start-date>


if (currentQName.equals("start-date")) {
         //return Java date the easiest way possible.
}

My solution involves saving all three than checking all possibilities and I want to avoid that if possible.

Tricky thing is that there are restriction originating from DTD, only YEAR is mandatory, if month is defined, than day is mandatory as well.

Thanks!

2
  • 1
    You can add restrictions that will only allow sensible values (e.g. 1-12 for month, 1-31 for day, +integer for year), but you can't handle leap years or years wo/ 31 days. Commented Feb 7, 2014 at 10:13
  • @PeterJaloveczki What exactly are you asking? By "Java date" do you mean a java.util.Date object? If month+day are optional, then I don't see how you can expect to create a date-time object like j.u.Date from just a year. Commented Feb 7, 2014 at 10:25

2 Answers 2

1
StringBuilder buf = new StringBuilder();
int year;
int month;
int day;

@Override
public void startElement(String uri, String localName, String qName,
        Attributes attributes) throws SAXException {
    if (localName.equals("year")) {
        buf.setLength(0);
    } else if (localName.equals("month")) {
        buf.setLength(0);
    } else if (localName.equals("day")) {
        buf.setLength(0);
    }
}

@Override
public void endElement(String uri, String localName, String qName)
        throws SAXException {
    if (localName.equals("start-date")) {
       doSomethingWith(year,month,day);
    } else if (localName.equals("year")) {
        year = Integer.parseInt(buf.toString());
    } else if (localName.equals("month")) {
        month = Integer.parseInt(buf.toString());
    } else if (localName.equals("day")) {
        day = Integer.parseInt(buf.toString());
    }
}

@Override
public void characters(char chars[], int start, int length)
        throws SAXException {
    buf.append(chars, start, length);
}
Sign up to request clarification or add additional context in comments.

1 Comment

make sure you call super or pass the events on somehow, otherwise debugging down the road might be difficult!
1

The following block will give you a format of YYYY or YYYY/MM or YYYY/MM/DD depending on what your XML looks like and it handles a few error scenarios. You can then turn around and format that into a java.util.Date object or whatever you want to use it for.

Please keep in mind when implementing any SAX filtering/handling that you should always call 'super' for any events you intercept to make sure you are passing the events on to any downstream handler otherwise they'll vanish from the stream and someone will have some trouble debugging at some point.

StringBuilder buf = null;

@Override
public void startElement(String uri, String localName, String qName,
        Attributes attributes) throws SAXException {

    if ("month".equals(localName) || "day".equals(localName)) {
        if (buf != null) {
            buf.append("/");
        } else {
            throw new SAXException("something went wrong, we received a month and day outside a start-date");
        }
    } else if ("start-date".equals(localName)){
        //there's another error condition that should be handled here if we encounter a start-date but we're already buffering
        buf = new StringBuilder();
    }
    super.startElement(uri,localName,qName);
}

@Override
public void endElement(String uri, String localName, String qName)
        throws SAXException {
    if ("start-date".equals(localName)) {
        //buf will be int he format of YYYY OR YYYY/MM OR YYYY/MM/DD depending on what was in your XML.
        doSomethingWith(buf.toString());
    }
    super.endElement(uri,localName,qName); 
}

@Override
public void characters(char chars[], int start, int length)
        throws SAXException {
    if (buf != null) {
        buf.append(chars, start, length);
    }
    super.characters(chars,start,length);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.