创建使用<all>和<any>元素</any> </all>打开的有效XSD

时间:2011-03-03 08:28:53

标签: xsd jaxb

我需要指定一个XSD来验证XML文档。 XSD将用于JAXB生成的Java绑定。 我的问题是指定可选元素,我不知道其名称以及我一般对解析不感兴趣。

XML文档的结构如下:

<TRADE>
  <TIME>12:12</TIME>
  <MJELLO>12345</MJELLO>
  <OPTIONAL>12:12</OPTIONAL>
  <DATE>25-10-2011</DATE>
  <HELLO>hello should be ignored</HELLO>
</TRADE>

重要的是,那个:

  • 我不能假设任何订单,下一个XML文档实例migtht有不同顺序的标签
  • 我只对解析某些标签感兴趣,有些是强制性的,有些是可选的
  • XML文档可以使用我不感兴趣解析的新元素进行扩展

我的XSD结构就像( 不是有效的xsd ):

<?xml version="1.0" encoding="ISO-8859-1"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <!-- *********************************************** -->
  <!-- Trade element definitions for the XML Documents -->
  <!-- *********************************************** -->

  <xs:complexType name="Trade">
    <!-- Using the all construction ensures that the order does not matter -->
    <xs:all>
      <xs:element name="DATE" type="xs:string" minOccurs="1" maxOccurs="1" />
      <xs:element name="TIME" type="xs:string" minOccurs="1" maxOccurs="1" />
      <xs:element name="OPTIONAL" type="xs:string" minOccurs="0" maxOccurs="1" />
      <xs:any minOccurs="0"/>
    </xs:all>
  </xs:complexType>

  <!-- TRADE is the mandatory top-level tag -->
  <xs:element name="TRADE" type="Trade"/>

</xs:schema>

因此,在此示例中:DATE和TIME是必需的(它们必须在XML中只有一次),OPTIONAL可能存在一次,然后我想指定,允许所有其他标记。订单无关紧要。

如何为此指定有效的XSD?

2 个答案:

答案 0 :(得分:5)

这是一个经典的解析器问题。

基本上,您的BNF是:

Trade    = whatever whatever*
whatever = "DATE"  | "TIME" | anything
anything = a-z a-z*

但这很暧昧。字符串“DATE”都可以在“DATE”和任何内容的任何规则下接受。

所以,如果你有

<TRADE>
  <TIME>12:12</TIME>
  <DATE>25-10-2011</DATE>
  <DATE>25-12-2011</DATE>
</TRADE>

目前尚不清楚是否应该接受这一点。

它可以被解释为

之一
"TIME", "DATE", anything
anything, anything, "DATE"
anything, anything, anything
"TIME", "DATE", anything
"TIME", "DATE", "DATE"
etc.

这一切归结为:如果你有一个结合随机序列的通配符,你就无法有意义地决定哪个令牌匹配哪个规则。

将可选元素与wilcard一起使用尤其没用。

您有两种选择:

  • 使用xs:sequence而不是xs:all
  • 不要使用通配符

据我了解,这两种选择都与您的意愿相冲突。

也许你可以构建一个匹配所有的通配符,除了 DATE,TIME等。

答案 1 :(得分:2)

将JAXB绑定到“已知”元素是否是一项艰难的要求? 如果没有,你基本上可以只有<any maxoccurs="unbounded" processContents="skip"/>作为你的xsd,然后从DOM树中选出你感兴趣的元素。

(参见here如何在没有数据绑定的情况下使用JAXB。)