【问题标题】:How can I get JAXB to generate empty tags for elements with restrictions?如何让 JAXB 为有限制的元素生成空标签?
【发布时间】:2017-03-23 21:28:12
【问题描述】:

我一直在阅读如何让 JAXB 在编组时生成空元素标签(即<name/>),似乎我需要指定一个空字符串“”。如果指定了元素,我的架构对某些需要至少 1 个字符的元素有限制。

我怎样才能让 JAXB 生成空元素标签,而不会在限制上引发验证错误?

编辑:

更新信息 - 我有一个元素 name,它在我的 XSD 中作为序列的一部分被引用。该元素在序列中是必需的,因为它没有minOccurs="0" 的属性。不幸的是,我无法控制更改 XSD,因此无法添加属性。

当我输入一个空字符串 "" 以便 jaxb 创建空元素时,我收到一个验证错误,因为 name 元素的限制为 <xs:minLength value="1"/> 我希望能够验证 XML 以检查其他问题,但跳过此特定验证。

【问题讨论】:

  • <name/> 和 <name></name> 表示相同的意思,它是一个空字符串,而不是缺少值。如果你的约束是minOccurs="0" 并且不允许空字符串,那么<name/> 是无效的,但是缺少name 标记是有效的,那么你为什么要明确地想要生成它呢?它违反了架构!
  • 我既没有得到</name> 也没有得到<name></name> 它根本不打印标签。问题是元素被指定为<xs:element ref="name"/>,因此序列需要标签,但名称元素具有 minLength "1" 和 maxLength "255" 的限制客户端不希望在该标签中指定名称,即为什么我只需要一个空标签就不会出现序列错误。
  • 所以如果元素是必需的,并且长度必须是1-256,那么一个空字符串是invalid,你的代码将值设置为null或@ 987654335@ 违反了约束,应该无法通过验证。没有标签是序列错误。有一个空标签是一个长度限制错误。两者都无效。
  • 我们正在调整这个应用程序并使用客户给我们的模式。有一个使用此模式的旧应用程序,使用空名称标签创建 XML,并且客户端认为该 XML 有效。我无法就他们所做的事情联系旧团队,并且客户希望架构能够正常工作,因为它与原始应用程序一起工作。有没有办法设置空标签并避免特定的验证?
  • Schema 不适用于旧应用程序,只是没有经过验证。停止验证或更改架构。

标签: java jaxb tags schema marshalling


【解决方案1】:

想出了如何解决和忽略特定验证。我为我的 JAXB 代码创建了一个实现 ValdationEventHandler 的事件处理程序,如下所示:

public class MyEventHandler implements ValidationEventHandler {

private static final Logger logger = Logger.getLogger(MyEventHandler.class);

@Override
public boolean handleEvent(ValidationEvent event) {

    if(event.getLocator().getObject() instanceof com.path.MyObject || 
            event.getMessage().contains("length = '0' is not facet-valid with respect to minLength '1' for type '#AnonType_name'")){
        return true;
    }
    logger.info("\nEVENT");
    logger.info("SEVERITY: " + event.getSeverity());
    logger.info("MESSAGE: " + event.getMessage());
    logger.info("LINKED EXCEPTION: " + event.getLinkedException());
    logger.info("LOCATOR");
    logger.info(" LINE NUMBER: " + event.getLocator().getLineNumber());
    logger.info(" COLUMN NUMBER: " + event.getLocator().getColumnNumber());
    logger.info(" OFFSET: " + event.getLocator().getOffset());
    logger.info(" OBJECT: " + event.getLocator().getObject());
    logger.info(" NODE: " + event.getLocator().getNode());
    logger.info(" URL: " + event.getLocator().getURL());
    return false;
}

在带有 JAXB Marshaller 的类中,我添加了这样的事件处理程序:

jaxbMarshaller.setEventHandler(new MyEventHandler());

当存在验证事件时,它会进入事件处理程序,检查它是否是正确的对象并纠正该对象上的错误,如果是,则返回 true,告诉编组器继续。如果不是这个错误,它会打印出事件的所有信息并返回false,所以编组失败。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多