【问题标题】:How to require an element based on a 'type' attribute value?如何要求基于“类型”属性值的元素?
【发布时间】:2016-04-30 05:30:44
【问题描述】:

我正在尝试为以下 XML 构建一个 XSD,并且我正在使用 JAXB 通过验证解组到 Java 对象。

验证规则是<JobParam> 中的前两个元素type = jobTypetype = customer 是必需的。 JobParam 中的所有其他人都是可选的。

如何为此创建 XSD?

<job>
    <jobName>core</jobName>
    <jobParams>
         <jobParam type="jobType">Scheduler</jobParam>
         <jobParam type="customer">Alphabet</jobParam>
         <jobParam type="mode">music</jobParam>
      </jobParams>
</job>

【问题讨论】:

    标签: xml xsd jaxb xsd-validation xml-validation


    【解决方案1】:

    您无法在 XSD 1.0 中表达您的验证规则。您必须在 Java 中针对您的 JAXB 创建的对象执行此操作,或者迁移到可以使用断言或条件类型分配的 XSD 1.1。

    但是,最好的解决方案是修复您的 XML 设计:

    • 没有必要在孩子的名字中重复父母的名字。 [轻微]
    • 如果元素类型是名称的一部分而不是属性值,则可以使用简单的 XSD 1.0 出现约束来表示您的验证规则。 [主要]

    以下是对您的 XML 所做的上述改进:

    <job>
        <name>core</name>
        <params>
             <type>Scheduler</type>
             <customer>Alphabet</customer>
             <mode>music</mode>
         </params>
    </job>
    

    您可能会考虑的另外两个改进:

    1. 删除 params 包装器,将其子代提升为 job 的子代。
    2. 如果您确实必须支持在 XSD 设计时未知的参数,请添加回 customParams 包装器。

    例如:

    <job>
        <name>core</name>
        <type>Scheduler</type>
        <customer>Alphabet</customer>
        <customParams>
           <customParam type="mode">music</customParam>
        </customParams>
    </job>
    

    这可以通过 XSD 1.0 中的基本出现约束与您关于 customermode 的验证规则一起简单地表示。

    【讨论】:

    • 谢谢。我希望我可以更改 xml,我同意你的建议。但这在目前是完全不可能的。此 xml 的客户端用户不愿意更新它。今天我在 Java 对象上处理这些验证。然而,并非所有情况都可以使用 Java 代码有效地处理。例如,当 xml 有重复的 jobParam 元素 Scheduler
    • 如果您无法重新设计 XML,那么您的选择是 (a) 迁移到 XSD 1.1,(b) 在 XSD 之外强制执行该约束(例如在 Java 中)或 (c) 删除必须存在 jobParam[@type='jobType']jobParam[@type='customer'] 的约束。给定原始 XML 设计,XSD 1.0 根本无法表达该约束。您的评论中提到的额外约束是相似的。 (在 Java 中都不应该很难实现——只是对于在 XSD 中以声明方式集中验证约束并不理想。)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-16
    • 2021-10-07
    • 2019-08-26
    • 1970-01-01
    • 2010-09-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多