【发布时间】:2018-09-14 01:52:26
【问题描述】:
我正在研究基于 XML 的配置文件的架构。
<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Configuration">
<xs:complexType>
<xs:sequence>
<xs:element name="Services">
<xs:complexType>
<xs:sequence>
<!--
Each service represents a specific web service. During the validation of the XML configuration
against the schema an additional check for multiple occurrences of the same service must take place to ensure proper configuration.
If support for more services is added increase maxOccurs accordingly. Currently supported are
* Service1
* Service2
* Service3
-->
<xs:element maxOccurs="3" name="Service">
<xs:complexType>
<xs:sequence>
<xs:element name="ConnectionStatusUsedFor">
<xs:complexType>
<xs:attribute name="Table" type="xs:string" use="required" />
<xs:attribute name="Column" type="xs:string" use="required" />
<xs:attribute name="Row" type="xs:unsignedByte" use="required" />
</xs:complexType>
</xs:element>
<!--
Used only by service of type DeviceService
-->
<xs:element minOccurs="0" maxOccurs="1" name="VersionInfo">
<xs:complexType>
<xs:sequence>
<xs:element name="Application" type="xs:string" default="Ultimate Software" />
<xs:element name="OS" type="xs:string" default="Debian 9" />
<xs:element name="Manufacturer" type="xs:string" default="Some company" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="port" type="xs:unsignedShort" use="required" />
<!--
The URI is added as a path to the address where the respective service is made available for the
clients to connect to. The format is
http://127.0.0.1:[port]/[uri]
with [port] being the value taken from the port-attribute
-->
<xs:attribute name="uri" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="Service1.soap"/>
<xs:enumeration value="Service2.soap"/>
<xs:enumeration value="Service3.soap"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="Timeout" type="xs:duration" use="required" />
<!--
The version of a service (see operation GetServiceVersion) defines which operations the service supports.
The limited range here is defined as the smallest and largest version number available among all
services. This also means that some services do not support a given higher version so additional
service-specific check must take place during the validation of the XML configuration against the
schema
-->
<xs:attribute name="version" use="required">
<xs:simpleType>
<xs:restriction base="xs:unsignedByte">
<xs:minInclusive value="0" />
<xs:maxInclusive value="5" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<!-- rest of configuration -->
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
以下是要针对 XSD 进行验证的 XML 文档示例:
<?xml version="1.0" encoding="utf-8" ?>
<Configuration>
<Services>
<!--
Service:
port The port that we listen to for incomming data from a client
uri The path for the client to access the respective web service
Note that all web services are hosted on localhost, which (given a
port and uri) always results in http://127.0.0.1:<port>/<uri> as the
service end point for the client to connect to
version The version of the web service. Based on it's value (an integer)
-->
<Service port="8081" uri="HelloWorldService1.soap" Timeout="PT30S" version="5"/>
<Service port="8085" uri="HelloWorldService2.soap" Timeout="PT30S" version="0"/>
<Service port="8082" uri="HelloWorldService3.soap" Timeout="PT30S" version="1">
<VersionInfo>
<Application>My Software</Application>
<OS>Debian 9</OS>
<Manufacturer>Hello World</Manufacturer>
</VersionInfo>
</Service>
</Services>
<!-- rest of configuration -->
</Configuration>
现在的问题是,我想将 Service 元素保留为添加的每个服务的公共元素,同时将实例限制为单个基于 URI。例如以下应该是不可能的(它是当前的 XSD):
<Service port="8082" uri="HelloWorldService3.soap" Timeout="PT30S" version="0">
<Service port="8085" uri="HelloWorldService3.soap" Timeout="PT30S" version="1">
原因:uri 属性对于两个Service 元素具有相同的值。其他属性可以(并且非常有意义)是相同的。
这可能吗?我可能会在某个时候移动到每个服务类型的单独元素,因为有些将包含未在其他上下文中使用的配置服务元素。
【问题讨论】:
-
您的问题标题谈到根据属性值限制元素的出现次数。您在解释中没有提到任何属性值,所以我根本不清楚您要强加的规则是什么。一般来说,这种规则需要 XSD 1.1,但最好在明确说明之前知道规则到底是什么。
-
@MichaelKay 将添加它。这是
uri的值,但是现在我看到该示例的每个属性都相同,因此确实令人困惑。我确实提到了 URI 是示例之前的限制规则。 -
我认为您只是说
Services中的每个Service都必须具有不同的@uri值,这就是xs:unique的用途。