minOccurs设置为0的XSD日期类型现在的值为“

时间:2011-09-28 08:27:51

标签: java spring xsd xmlbeans

如果我没有提供足够的信息,请提前原谅我,这是我看到的一个问题,并且负责修复,但我最初并没有亲自编写此代码(已经移动过的人)。

我们正在使用Apache XMLBeans从一组XSD生成一些Java类。然后,我们的Web应用程序生成Web HTML表单以创建这些类的实例(或修改现有类的字段)。把它放到一些背景中;我们的一个XSD代表一个人。然后,我们可以使用通用表单生成代码为用户生成HTML表单,以提供有关特定人员的信息。有许多与人相关的日期属性,例如出生日期。

我最近对项目的结构和依赖关系进行了一些实质性的更改,但没有直接与代码生成这些Java类和HTML表单的相关内容。在这些更改完成之前,现在,如果没有设置任何值,则所有日期字段的值都为<xml-fragment uid="theAttributesId"/>。在XSD中,这些日期属性/元素将minOccurs属性设置为0(因此应该是可选的)。如果我将每个属性的nillable属性设置为true,则可能不再存在。

花了一些时间调试后,我可以看到空日期值不是有效值,除非nillable为真。在XMLBeans类XmlObjectBase中,validate方法为null日期字段返回false。我不明白的是改变了什么,为什么现在需要nillable属性。依赖关系已经改变,但是比较XMLBean版本它们看起来都是一样的:

我们的web应用程序的lib目录中有三个包含类XmlObjectBase的jar; tika-app-0.7,xbeans-2.2.0和xmlBeans-2.3.0。在大规模重组之前,所有版本都与lib目录相同。 XSD文件没有更改。有什么?

到目前为止,我找到了以下有助于我调查的链接:

我已经接受了,如果没有大量的时间,解决这个问题的唯一现实方法就是添加nillable属性。但是,我并不热衷于为XSD中的所有日期元素添加它。幸运的是,我定义了3个日期基础类型,所有日期元素都是。我尝试将基本类型的默认nillable属性修改为true但没有成功:

原始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"/>。跆拳道?从我所读到的,应该意味着它评估为''。嗯...

另一个编辑:

我对这个问题感到非常厌倦,所以开始研究最新的网络应用程序和运行早期代码库的应用程序之间的差异。我在调试时看到的主要区别是:

新代码库:调用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和值的setter之间,有很多Spring类。新代码库和旧(工作)代码库之间的关键区别是Spring版本。

新代码库依赖于spring-context-3.0.5.RELEASE,而旧代码依赖于spring-context-2.5.6.SEC02。

任何建议都会非常感谢!

2 个答案:

答案 0 :(得分:1)

Nillable不是你自己实现的东西。它是XSD定义的一部分。

xsi:nil="true"用于表示字段的实例没有值。

nillable="true"用于表示该字段的模式定义不允许任何值。

或者我错过了这一点?

答案 1 :(得分:1)

完成了大量的调试后,我得到了答案 - 我现在知道两个版本之间的区别是什么:

Spring类org.springframework.web.servlet.tags.form.ValueFormatter在版本2.5.6.SEC02和3.0.5.RELEASE之间略有不同。

方法getDisplayString的实现在两个版本之间有所不同:

2.5.6.SEC02(在我的应用程序中正常工作

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);

当date没有值时,propertyEditor.getAsText()返回的文本总是为我返回null,因此使用'value'属性。我相信这个问题实际上是在我的应用程序中的一些代码中(自定义XmlBaseTypePropertyEditor似乎是错误的)并且我认为Spring更改没有问题。

抱歉浪费任何人的时间。不管怎样,谢谢。