Типы дат XSD с minOccurs, установленными в 0, теперь имеют значение "<xml-фрагмент ..." (по умолчанию nillable равен false) - PullRequest
2 голосов
/ 28 сентября 2011

Простите меня заранее, если я не предоставил достаточно информации, это проблема, с которой я сталкиваюсь, и мне было поручено исправить ее, но я лично не писал этот код изначально (человек, который сделал это, ушел).

Мы используем Apache XMLBeans для генерации некоторых классов Java из набора XSD. Наше веб-приложение затем генерирует веб-форму HTML для создания экземпляров этих классов (или изменения полей существующих классов). Чтобы поместить это в некоторый контекст; один из наших XSD представляет человека. Затем мы можем использовать наш общий код генерации форм для генерации HTML-формы, чтобы пользователь мог предоставить информацию о конкретном человеке. Существует несколько атрибутов даты, связанных с человеком, например, Дата рождения.

Недавно я внес некоторые существенные изменения в структуру и зависимости проекта, но ничего, что напрямую связано с кодом, не генерирует эти классы Java и форму HTML из них. До того, как эти изменения были сделаны, все работало, теперь все поля даты имеют значение <xml-fragment uid="theAttributesId"/>, если для них не было установлено какое-либо значение. В XSD эти атрибуты / элементы даты имеют атрибут minOccurs, установленный в 0 (и, следовательно, должен быть необязательным). Если для каждого атрибута установить для атрибута nillable значение true, вероятно, он больше не существует.

Потратив некоторое время на отладку, я вижу, что пустое значение даты не является допустимым, если nillable не имеет значение true. В классе XMLBeans XmlObjectBase метод validate возвращает false для пустых полей даты. Чего я не понимаю, так это того, что изменилось и почему теперь нужен атрибут nillable. Зависимости изменились, но при сравнении версий XMLBean все они кажутся одинаковыми:

В каталоге lib нашего веб-приложения есть три jar-файла, которые содержат класс XmlObjectBase; tika-app-0.7, xbeans-2.2.0 и xmlBeans-2.3.0. Все версии идентичны каталогу lib до масштабной реструктуризации. Файлы XSD не изменились. Что имеет?

Я нашел следующие ссылки, которые помогли в моих исследованиях:

Я согласился, что, возможно, единственный реалистичный способ решения этой проблемы без значительного количества времени - это добавить атрибут nillable. Однако я не хочу добавлять его для всех элементов даты в XSD. К счастью, у меня есть 3 типа базы данных, которые определены как все элементы даты. Я попытался изменить атрибут nillable по умолчанию базовых типов, чтобы истина без успеха:

Исходный NonFutureDateBaseType:

<xs:complexType name="nonFutureDateType">
    <xs:simpleContent>
        <xs:extension base="cr:nonFutureDateBaseType">
            <xs:attribute name="uid" type="xs:int" />
        </xs:extension>
    </xs:simpleContent>
</xs:complexType>

(где cr:nonFutureDateBaseType - простой тип с ограничением стандартного типа даты XSD)

Новое с попыткой nillable по умолчанию как true:

<xs:complexType name="nonFutureDateType">
    <xs:simpleContent>
        <xs:extension base="cr:nonFutureDateBaseType">
            <xs:attribute name="uid" type="xs:int" />
    <xs:attribute name="nillable" type="xs:boolean" default="true" />
        </xs:extension>
    </xs:simpleContent>
</xs:complexType>

У кого-нибудь есть предложения относительно того, почему вышеперечисленное не работает? Или что еще я должен посмотреть?

Извиняюсь за длинный вопрос (и отсутствие форматирования - по какой-то причине у меня нет SO изображений / значков) и заранее спасибо.

Подробнее Редактировать

Я только что посмотрел в базе данных на XML, который представляет человека. У меня есть что-то вроде этого:

<PERSON>
    ...
    <BIRTH_DATE uid="12" 
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
                xsi:nil="true" />
    ...
</PERSON>

А затем значение BIRTH_DATE оценивается как <xml-fragment uid="theAttributesId"/>. WTF? Из того, что я прочитал, это должно означать, что оно оценивается как «». Ммм ...

Другое Редактирование:

Я серьезно устала от этой проблемы, поэтому приступила к изучению различий между последним веб-приложением и тем, которое использует более раннюю кодовую базу. Основное различие, которое я вижу при отладке, заключается в следующем:

Новая кодовая база: вызов java.beans.PropertyEditorSupport.getValue () возвращает <xml-fragment uid="12"/>

Старая кодовая база: вызов java.beans.PropertyEditorSupport.getValue () возвращает <xml-fragment uid="12" xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>

Между моим JSP, который генерирует форму и установщик значения, существует множество классов Spring.Ключевым отличием между новой кодовой базой и старой (рабочей) кодовой базой является версия Spring.

Новая кодовая база зависит от spring-context-3.0.5.RELEASE, тогда как старая зависит от spring-context-2.5.6.SEC02.

Любые предложения приветствуются!

Ответы [ 2 ]

1 голос
/ 01 ноября 2011

После значительного объема отладки у меня есть ответ - теперь я знаю, в чем разница между двумя версиями:

Класс Spring org.springframework.web.servlet.tags.form.ValueFormatter имеет небольшую разницу между версией 2.5.6.SEC02 и 3.0.5.RELEASE.

Реализация метода getDisplayString отличается между двумя версиями:

2.5.6.SEC02 (работает правильно в моемapplication )

if (propertyEditor != null && !(value instanceof String)) {
    try {
        propertyEditor.setValue(value);
        return getDisplayString(propertyEditor.getAsText(), htmlEscape);
    }
    catch (Throwable ex) {
        // The PropertyEditor might not support this value... pass through.
        return getDisplayString(value, htmlEscape);
    }
}
else {
    return getDisplayString(value, htmlEscape);
}

3.0.5.RELEASE (Показать фрагмент XML, если значение даты не установлено):

if (propertyEditor != null && !(value instanceof String)) {
    try {
        propertyEditor.setValue(value);
        String text = propertyEditor.getAsText();
        if (text != null) {
            return getDisplayString(text, htmlEscape);
        }
    }
    catch (Throwable ex) {
        // The PropertyEditor might not support this value... pass through.
    }
}
return getDisplayString(value, htmlEscape);

Текст, возвращаемый из propertyEditor.getAsText (), всегда возвращает мне значение null, когда у даты нет значения и, следовательно, используется свойство 'value'.Я полагаю, что проблема на самом деле в каком-то коде в моем приложении (пользовательский XmlBaseTypePropertyEditor является ошибкой, как кажется), и я полагаю, что нет никаких проблем с изменением Spring.

Извините, что зря потратил время.В любом случае, спасибо.

1 голос
/ 28 сентября 2011

Nillable - это не то, что вы реализуете сами. Это часть определения XSD.

xsi:nil="true" используется для указания того, что экземпляр поля не имеет значения.

nillable="true" используется для указания того, что определение схемы поля не допускает значения.

Или я упустил суть?

...