#java #parsing
#java #синтаксический анализ
Вопрос:
Это первый раз, когда я интенсивно работаю с XML на Java. Код использует JAXB для создания классов, а затем синтаксического анализа. У меня есть XML с датой…
Класс был сгенерирован JAXB из моего XML. Он сгенерировал следующее для поля:
@XmlElement(name = "CoverStartDate", required = true)
protected XMLGregorianCalendar coverStartDate;
В моей логике у меня есть следующее
xxxx.setCoverStartDate(xmlGregorianCalendar(theDate)
Существует метод XMLGregorianCalendar, который выглядит примерно так:
GregorianCalendar gregorianCalendar = new GregorianCalendar();
gregorianCalendar.setTime(date);
return DatatypeFactory.newInstance().newXMLGregorianCalendar(gregorianCalendar);
В моем возвращаемом XML, который был сгенерирован, была указана дата с указанным временем. Мне нужна только дата (год-месяц-день).
Есть предложения?
Спасибо
Ответ №1:
Используйте DatatypeFactory.newXMLGregorianCalendarDate(...)
вместо простого использования любого из DatatypeFactory.newXMLGregorianCalendar(...)
методов.
Я не знаю, что находится theDate
в вашем фрагменте кода, однако, если вы работаете с Date
объектами, вы можете использовать следующее.
public static XMLGregorianCalendar setCoverStartDate(Date date) throws DatatypeConfigurationException {
Calendar calendar = Calendar.getInstance();
date.setTime(date.getTime());
return DatatypeFactory.newInstance().newXMLGregorianCalendarDate(
calendar.get(Calendar.YEAR),
calendar.get(Calendar.MONTH) 1,
calendar.get(Calendar.DAY_OF_MONTH),
getTimeZone(calendar));
}
public static int getTimeZone(Calendar calendar) {
return (int) TimeUnit.MINUTES.convert(calendar.get(Calendar.ZONE_OFFSET), TimeUnit.MILLISECONDS);
}
(Обратите внимание, что calendar's
Calendar.ZONE_OFFSET
это в миллисекундах, а newXMLGregorianCalendarDate(...)
метод ожидает значение часового пояса в минутах, поэтому его необходимо преобразовать.)
(Также обратите внимание, что Calendar's
индекс месяца основан на 0, а XMLGregorianCalendar's
месяц основан на 1.)
Если это не работает, то схема XML, которую вы использовали для создания своих классов JAXB, вероятно, ошибочна: возможно, в ней не указано использование типа схемы xs:date
XML (возможно, он использует xs:dateTime
вместо этого).
Только один последний совет: создайте свои классы JAXB вручную. Затем вы можете указать аннотации, например @XmlSchemaType
, в полях ваших классов, что дает вам гораздо больше контроля.
Комментарии:
1. 1 для
@XmlSchemaType
получения дополнительной информации о том, как его можно использовать со свойствами даты / времени, см.: blog.bdoughan.com/2011/01/jaxb-and-datetime-properties.html2. Это было здорово. Я реализовал его, и он выглядит намного лучше. Теперь вместо моего XML выглядит так: <CoverStartDate>2011-01-01T00:00:00.000 02:00</ Дата начала обложки>. Это выглядит так: <CoverStartDate>2011-01-01 02:00</CoverStartDate> . Есть ли что-нибудь еще, что я могу сделать, чтобы избавиться от часового пояса too…so он отображает только часть даты?
3. Хорошо … извините, я понял это. Я использовал DatatypeConstants. FIELD_UNDEFINED как параметр часового пояса.
Ответ №2:
Вам нужно использовать DateFormatter, который форматирует его только в часть ДАТЫ, игнорируя время.
Что-то вроде: (new SimpleDateFormat("yyyy MMMM dd")).format(theDate));
Ответ №3:
Вы можете использовать файл внешней привязки JAXB, чтобы GregorianCalendar
сгенерировать a в вашей объектной модели. Это избавит вас от необходимости выполнять преобразование. Пример выполнения чего-то подобного можно найти здесь:
javax.xml.bing.DatatypeConverter
Класс может быть полезен при создании необходимого XmlAdapter
.
Ответ №4:
Это работает для меня:
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
Date fechaBajaPrevista = Calendar.getInstance().getTime();
XMLGregorianCalendar calendar = DatatypeFactory.newInstance().newXMLGregorianCalendar(
new SimpleDateFormat("yyyy-MM-dd").format(fechaBajaPrevista));