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

Mor*_*ank 7 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>
Run Code Online (Sandbox Code Playgroud)

重要的是,那:

  • 我不能假设任何顺序,并且下一个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>
Run Code Online (Sandbox Code Playgroud)

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

如何为此指定有效的XSD?

Jør*_*sen 5

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

基本上,您的BNF是:

Trade    = whatever whatever*
whatever = "DATE"  | "TIME" | anything
anything = a-z a-z*
Run Code Online (Sandbox Code Playgroud)

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

所以,如果你有

<TRADE>
  <TIME>12:12</TIME>
  <DATE>25-10-2011</DATE>
  <DATE>25-12-2011</DATE>
</TRADE>
Run Code Online (Sandbox Code Playgroud)

目前还不清楚是否应该接受.

它可以解释为其中之一

"TIME", "DATE", anything
anything, anything, "DATE"
anything, anything, anything
"TIME", "DATE", anything
"TIME", "DATE", "DATE"
etc.
Run Code Online (Sandbox Code Playgroud)

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

将可选元素与wilcard一起使用尤其没有意义.

您有两种选择:

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

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

也许你可以构建符合一切通配符除了 DATE,TIME等.