XSD - 使用多个“具体”子元素类型定义“抽象”基本元素类型

时间:2016-10-23 12:17:51

标签: java xml xsd

我的目标是拥有一个定义消息过滤器的XML。 根<Filter>元素将包含零个或多个“FilterRule”,它可以是<Include><Exclude>规则元素之一。

<Include><Exclude>都是相同的元素,仅因其名称而不同 我想定义一个名为“FilterRule”的“基础”类型。此类型将是“抽象的”,不能在实际的XML中使用 然后,我想定义两个“具体”类型:“包含”和“排除”,它们将从基类型继承。

每个“FilterRule”可以包含零个或多个子“FilterRule”。

两个示例用法:

<?xml version="1.0" encoding="UTF-8"?>
<Filter>
  <!-- By default all the messages are included, so let's first exclude everything: -->
  <Exclude type="regex" filteredEntity="ORIGINAL_MESSAGE" value=".*">
    <!-- And now include only the *Important* messages: -->
    <Include type="regex" filteredEntity="ORIGINAL_MESSAGE" value=".*Important.*"/>
  </Exclude>
</Filter>

<?xml version="1.0" encoding="UTF-8"?>
<Filter>
  <!-- By default all the messages are included, lets exlcude the annoying and redundant ones: -->
  <Exclude type="regex" filteredEntity="ORIGINAL_MESSAGE" value="AnnoyingSource:.*"/>
  <Exclude type="regex" filteredEntity="ORIGINAL_MESSAGE" value=".*: Redundant Message"/>
</Filter>

我是XSD的新手所以我可能做的事情非常糟糕......这就是我到目前为止(这个XSD本身甚至没有验证):

<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:complexType name="FilterRule">
    <xs:sequence>
      <xs:element name="FilterRule" maxOccurs="unbounded" minOccurs="0"/>
    </xs:sequence>
    <xs:attribute type="filterType" name="filterType"/>
    <xs:attribute type="filteredEntity" name="filteredEntity"/>
    <xs:attribute type="xs:string" name="value" />
  </xs:complexType>

  <xs:complexType name="Exclude">
    <xs:complexContent>
      <xs:extension base="FilterRule"/>
    </xs:complexContent>
  </xs:complexType>

  <xs:complexType name="Include">
    <xs:complexContent>
      <xs:extension base="FilterRule"/>
    </xs:complexContent>
  </xs:complexType>

  <xs:simpleType name="filterType">
    <xs:restriction base="xs:string">
      <xs:enumeration value="REGEX"/>
      <xs:enumeration value="EQUALS"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="filteredEntity">
    <xs:restriction base="xs:string">
      <xs:enumeration value="ORIGINAL_MESSAGE"/>
      <xs:enumeration value="PROCESSED_MESSAGE"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:element name="Filter" maxOccurs="1" minOccurs="1">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="FilterRule" maxOccurs="unbounded" minOccurs="0"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

那么,我做错了什么?

P.S。 XSD将用于生成JAXB(Java)类。

2 个答案:

答案 0 :(得分:1)

您为什么要尝试使用扩展元素。 Include和Exclude的类型相同,应使用相同的类型。元素名称可能有所不同。

示例XSD:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:complexType name="FilterRuleType">
        <xs:sequence>
            <xs:element name="Exclude" type="FilterRuleType" maxOccurs="unbounded" minOccurs="0"/>
                <xs:element name="Include" type="FilterRuleType" maxOccurs="unbounded" minOccurs="0"/>
        </xs:sequence>
        <xs:attribute type="filterType" name="filterType"/>
        <xs:attribute type="filteredEntity" name="filteredEntity"/>
        <xs:attribute type="xs:string" name="value"/>
    </xs:complexType>

    <xs:simpleType name="filterType">
        <xs:restriction base="xs:string">
            <xs:enumeration value="REGEX"/>
            <xs:enumeration value="EQUALS"/>
        </xs:restriction>
    </xs:simpleType>
    <xs:simpleType name="filteredEntity">
        <xs:restriction base="xs:string">
            <xs:enumeration value="ORIGINAL_MESSAGE"/>
            <xs:enumeration value="PROCESSED_MESSAGE"/>
        </xs:restriction>
    </xs:simpleType>
    <xs:element name="Filter">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="Exclude" type="FilterRuleType" maxOccurs="unbounded" minOccurs="0"/>
                <xs:element name="Include" type="FilterRuleType" maxOccurs="unbounded" minOccurs="0"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

答案 1 :(得分:0)

以下是您的架构如何使用Saxon架构处理器失败:

Error at xs:element on line 37 column 59 of test.xsd:
  Attribute @maxOccurs is not allowed on element <xs:element>
Error at xs:element on line 37 column 59 of test.xsd:
  Attribute @minOccurs is not allowed on element <xs:element>
Schema processing failed: 2 errors were found while processing the schema

这是一个非常简单的错误(元素可能出现的次数始终定义在您使用元素定义的位置,而不是在您定义元素定义的位置。)当您解决此问题时,显而易见的方法是删除有问题的属性,架构验证。