【问题标题】:XSD dynamic enumeration based on XML基于 XML 的 XSD 动态枚举
【发布时间】:2013-11-12 23:57:05
【问题描述】:

假设我有以下 XML 文档:

<root>
  <genres> 
    <genre name="comedy" />
    <genre name="academic" />
  </genres>
  <authors>
    <author name="Thomson">
      <writings>
        <writing genre="academic">The text book</writing>
        <writing genre="comedy">The worst comedy</writing>
      <writings>
    </author>
  </authors>
  <readers>
    <reader name="Phil">
      <read writenBy="Thomson">The text book</read>
    </reader>
    <reader name="John" />
  </readers>
</root>

如您所见,“reader”元素可能没有“read”子元素。
但是,我希望验证过程确保没有以下条目:

<reader name="Paul">
  <read writtenBy="Thomson">A writing the author never wrote</read>
</reader>

我可以做的是通过使用键和 keyrefs 来限制属性可以基于先前定义的属性的值(请参阅accepted answer)。基于此,我可以确保“writtenBy”属性实际上是指作者的姓名,或者作品的流派属性来自先前定义的流派。

我知道您可以在 XSD 文档上对枚举进行硬编码(请参阅accepted answer)。
此外,您可以使用断言(在 XSD 1.1 中)根据 XML 中包含的信息进行更灵活的枚举(请参阅accepted answer)。
但我不能使用这些方法,因为它们是硬编码的。 有没有办法对元素值进行类似的检查,就像我目前对属性值所做的那样?

【问题讨论】:

    标签: xml xsd xsd-validation


    【解决方案1】:

    有几种可能性。首先,您可以使用 key 和 keyref 做一些聪明的事情,检查 read 元素的内容是否是相应作者的 writing 元素的内容。

    不过,给每个写入一个 ID 并让 read 元素引用该 ID 会更简单。如果消除了冗余,就消除了检查一致性的需要。当然,出于显示目的,您始终可以使用 XSLT 来获取作者和作者的姓名。

    如果您无法进一步推动 key 和 keyref,并且您不想消除 XML 表示中的冗余,那么检查您指定的约束的最简单方法是使用断言,无论是在 XSD 1.1 中还是在 Schematron 中.

    其中,我推荐第二个(重组 XML 以使有效性约束更简单,更容易检查)。当然,您的偏好可能会有所不同。

    【讨论】:

    • 是的,我编的例子可以改进。但是,您确实给了我一个好主意,其中涉及定义一个具有唯一 id 的“枚举”,然后使用键和 keyrefs 来验证它们。
    【解决方案2】:

    如果我正确理解您的要求,key/keyref 可以几乎处理它。在共同祖先(根)级别,您可能希望使用

    定义一个键
    * selector = authors/author/writings/writing
    * fields = 
      (a) ../../@name 
      (b) .
    

    并用

    定义一个keyref
    * selector = readers/reader/read
    * fields =
      (a) @writtenBy
      (b) .
    

    唯一的问题是您不能使用../../@name - 您不能在允许键和keyrefs 的XPath 子集中引用祖先的属性。除了 (a) 更改 XML 设计以在“writing”元素中复制作者姓名,或者 (b) 改用 XSD 1.1 断言之外,我看不到解决方案。

    【讨论】:

    • 我在考虑改变设计并给每个写一个ID作为属性。我认为这样会更容易。使用断言听起来很有趣,但我见过的所有示例都使用预定义的枚举。你碰巧有一个简单的例子来解释它吗?也许是一个示例的链接?
    • 不,我没有任何例子。 (如果我可以这么说,你似乎相当依赖于寻找其他人已经编写的代码......)
    猜你喜欢
    • 2018-01-27
    • 1970-01-01
    • 2012-11-19
    • 1970-01-01
    • 2014-07-26
    • 1970-01-01
    • 2020-08-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多