XSD 中以分号分隔的类型列表

Semicolon separated list of types in XSD

我有一个 XML 属性,它必须接受以分号分隔的字符串列表。我想创建一个 XSD 来指定该输入的所有可能值。

例如:

<User role="Admin;Publisher;Editor" />

我知道我可以像这样创建一个简单的类型:

<xs:attribute name="role">
  <xs:simpleType>
    <xs:restriction base="xs:string">
      <xs:enumeration value="Admin"/>
      <xs:enumeration value="Editor"/>
      <xs:enumeration value="Proofreader"/>
      <xs:enumeration value="Publisher"/>
    </xs:restriction>
  </xs:simpleType>
</xs:attribute>

但这将它限制为只有一个值。

我知道我也可以使用正则表达式。但是我如何将两者结合起来呢?如果我使用像 [^;]+ 这样的正则表达式,那么我该如何验证这些值?

我可以制作一个包含那些 role 枚举列表的正则表达式吗?

或者只是一个正则表达式,强制它成为这些枚举值的列表,顺序不限,中间有分号? (A;C;BA;B;A等,其中ABC为指定词。)

这可能是可行的,但不可取。您可以想出一个枚举所有可能组合的限制,例如:

<xs:enumeration value="Admin;Editor;Proofreader;Publisher" />
<xs:enumeration value="Admin;Editor;Proofreader" />
<xs:enumeration value="Admin;Editor" />

等会有很多排列,并且随着您继续添加更多角色,列表将呈指数增长。

您真正应该考虑的是将您的 XML 和架构重构为更类似于以下内容:

<User>
  <role>Admin</role>
  <role>Editor</role>
</User>

如果你真的坚持仍然使用属性,你可以将属性放在角色元素上,如果你想指定角色元素的子元素并且没有混合内容节点,这可能很有用:

<User>
  <role name="Admin"><roleDescription>An administrator of the system</roleDescription></role>
  <role name="Editor"><nodesICanEdit>All</nodesICanEdit></role>
</User>

Dan Field 的回答是正确的:正确的做法是修复 XML 的设计。

如果你做不到(为什么不呢?你到底是怎么参与到一个损坏的设计在修复之前就被冻结的项目中的?你真的想参与这个项目吗?),一个简单的解决方法是在验证之前将数据从指定格式转换为更容易验证的格式。

  • 您可以按照 Dan Field 的建议将 role 作为 child。

    <User>
      <role>Admin</role>
      <role>Editor</role>
    </User>
    

    这里'role'的类型和你样本中@role的匿名类型是一样的

  • 您可以将角色作为元素:

    <User>
      <Admin/>
      <Editor/>
    </User>
    

    在这里,xs:all 可用于允许可选角色元素以任何顺序出现。

  • 您可以有一个 white-space 分隔的角色名称列表:

    <xs:simpleType name="rolename">
      <xs:restriction base="xs:string">
        <xs:enumeration value="Admin"/>
        <xs:enumeration value="Editor"/>
        <xs:enumeration value="Proofreader"/>
        <xs:enumeration value="Publisher"/>
      </xs:restriction>
    </xs:simpleType>
    <xs:simpleType name="rolelist">
      <xs:list itemType="tns:role"/>
    </xs:simpleType>