2

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

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

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

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

我们的 Web 应用程序的 lib 目录中有三个 jar,其中包含 XmlObjectBase 类;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 和值的设置器之间,有很多 Spring 类。新代码库和旧(工作)代码库之间的主要区别在于 Spring 版本。

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

任何建议将不胜感激!


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

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

nillable="true"用于指示字段的架构定义不允许值。

还是我错过了重点?

4

2 回答 2

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

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

很抱歉浪费了任何人的时间。不管怎么说,还是要谢谢你。

于 2011-11-01T15:17:05.730 回答
1

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

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

nillable="true"用于指示字段的架构定义不允许值。

还是我错过了重点?

于 2011-09-28T08:56:31.660 回答