Как мне проанализировать XML-файл с помощью Digester Commons и заполнить его объектом java.util.Date? - PullRequest
1 голос
/ 02 ноября 2009

Пример XML.

<person>
  <name>Joe Dirt</name>
  <ssn>123-45-6789</ssn>
  <dob>07/04/1981</dob>
</person>

Образец класса Java

public class Person(){
  private String name;
  private String ssn;
  private java.util.Date dob;
.....
}

Пример правил варочного котла

<?xml version="1.0"?>
<digester-rules>
  <pattern value="message">
      <object-create-rule classname="Person" />
      <bean-property-setter-rule pattern="name" propertyname="name" />
      <bean-property-setter-rule pattern="ssn" propertyname="ssn" />
      <bean-property-setter-rule pattern="dob" propertyname="dob" />
 </pattern>
</digester-rules>

Ответы [ 2 ]

6 голосов
/ 02 ноября 2009

Должен быть в состоянии зарегистрировать DateConverter, и все должно работать:

import org.apache.commons.beanutils.Converter;

class MyDateConverter implements Converter {
    @Override
    public Object convert(Class clazz, Object value) {
        if (clazz.equals(Date.class)) {
            SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
            try {
                return sdf.parse((String) value);
            } catch (ParseException pe) {
                throw new IllegalArgumentException(pe);
            } catch (ClassCastException cce) {
                throw new IllegalArgumentException(cce);
            }
        } else {
            throw new IllegalArgumentException("Expected Date class");
        }
    }
}

......

import org.apache.commons.beanutils.ConvertUtils;

@Test
public void testXmlRules() throws Exception {
    ConvertUtils.register(new MyDateConverter(), Date.class);
    Digester digester = DigesterLoader.createDigester(new InputSource(this
            .getClass().getResourceAsStream("rules.xml")));
    Person person = (Person) digester.parse(this.getClass()
            .getResourceAsStream("person.xml"));
    Assert.assertEquals("Joe Dirt", person.getName());
    Assert.assertEquals("123-45-6789", person.getSsn());
    Assert.assertEquals(new SimpleDateFormat("dd/MM/yyyy")
            .parse("07/04/1981"), person.getDob());
}
1 голос
/ 02 ноября 2009

Я когда-то сам сталкивался с этим вопросом. Я не нашел никакого стандартного способа сделать это. Лучшее, что я придумал, было это:

digester.addRule(ROOT + "/lastBuildDate", new Rule() {
  public void body(final String namespace, final String name, final String text) throws Exception {
    Message message = (Message) getDigester().peek();
    if (text == null || text.trim().equals("")) {
      message.setDate(new Date());
    } else {
      try {
        message.setDate(parseDate(text));
      } catch (final ParseException e) {
        Log.warn("failed to parse date: " + text, e);
        message.setDate(new Date());
      }
    }
  }
});

Date parseDate(String text) throws ParseException {
  // left as an exercise to the reader
}

Я не могу помочь с использованием пользовательских правил из вашего XML-метки, так как всегда предпочитал создавать метки программно.

В качестве обходного пути вы можете создать дополнительный установщик в своем классе Person:

public void setDobAsString(String dob) throws ParseException {
    setDob(parseDate(dob));
}
...