Use types in XSD, close #99

This commit is contained in:
~lucidiot 2022-05-25 16:56:49 +02:00 committed by Lucidiot
parent 80556cacd7
commit c364aca178
Signed by: lucidiot
GPG Key ID: 3358C1CA6906FB8D
1 changed files with 412 additions and 357 deletions

607
itsb.xsd
View File

@ -1,4 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
ITSB XML Schema
Copyright (C) 2022 ~lucidiot
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<xs:schema
targetNamespace="http://tilde.town/~lucidiot/itsb/itsb.xsd"
version="1.0"
@ -7,7 +24,7 @@
xmlns:itsb="http://tilde.town/~lucidiot/itsb/itsb.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
<xs:complexType name="itsbURL">
<xs:complexType name="URI">
<xs:simpleContent>
<xs:extension base="xs:anyURI">
<xs:attribute name="verify-ssl" type="xs:boolean" use="optional" default="true">
@ -23,41 +40,307 @@
</xs:simpleContent>
</xs:complexType>
<xs:element name="itsb">
<xs:complexType name="CurlHeader">
<xs:annotation>
<xs:documentation>
This schema describes both the structure for the directory page of ITSB
and the list of syndication feeds either inventoried or generated by ITSB.
This is meant to be used as a central place to hold feed configuration and
reduce duplication.
A HTTP header sent along with the request.
</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element name="section" minOccurs="1" maxOccurs="unbounded">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="name" type="xs:string" use="required" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="CurlCommand">
<xs:annotation>
<xs:documentation>
A separate section displayed in an HTML directory.
Should be ignored by machines.
Perform an HTTP request using `curl`.
</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element name="content" minOccurs="0" maxOccurs="unbounded" type="xs:string">
<xs:element name="url" type="URI">
<xs:annotation>
<xs:documentation>
Raw, encoded HTML content that should be displayed as-is in the section.
Can be ignored by machines.
URL of the original HTML webpage that will be retrieved to be converted into a feed.
</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="source" minOccurs="0" maxOccurs="unbounded">
<xs:element name="header" type="CurlHeader" minOccurs="0" maxOccurs="unbounded" />
<xs:element name="requestBody" type="xs:string" minOccurs="0">
<xs:annotation>
<xs:documentation>
Optional request body sent along with the request. When this element is used, the request becomes a POST request.
</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:simpleType name="PupOutputFormat">
<xs:annotation>
<xs:documentation>
Output format of a `pup` command.
</xs:documentation>
</xs:annotation>
<xs:restriction base="xs:string">
<xs:enumeration value="json">
<xs:annotation>
<xs:documentation>Output the selected tags as JSON (default).</xs:documentation>
</xs:annotation>
</xs:enumeration>
<xs:enumeration value="text">
<xs:annotation>
<xs:documentation>Output the selected tags' inner text.</xs:documentation>
</xs:annotation>
</xs:enumeration>
<xs:enumeration value="html">
<xs:annotation>
<xs:documentation>Output the selected tags as HTML.</xs:documentation>
</xs:annotation>
</xs:enumeration>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="PupCommand">
<xs:annotation>
<xs:documentation>
Apply a CSS 3 selector using `pup` on the HTML webpage.
</xs:documentation>
</xs:annotation>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="output" use="optional" type="PupOutputFormat" default="json">
<xs:annotation>
<xs:documentation>
Output format to use. Defaults to JSON.
</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="Xml2JsonCommand">
<xs:annotation>
<xs:documentation>
Run XML to JSON conversion using xmltodict.
</xs:documentation>
</xs:annotation>
</xs:complexType>
<xs:complexType name="XmlNamespace">
<xs:annotation>
<xs:documentation>
An XML namespace abbreviation to be recognized by xmltodict.
</xs:documentation>
</xs:annotation>
<xs:simpleContent>
<xs:extension base="xs:anyURI">
<xs:attribute name="prefix" type="xs:string" use="optional" default="">
<xs:annotation>
<xs:documentation>
The namespace prefix to use in the XML output. When not defined, this will become the default prefix (xmlns).
</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="Json2XmlCommand">
<xs:annotation>
<xs:documentation>
Run JSON to XML conversion using xmltodict.
</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element name="namespace" type="XmlNamespace" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="short-empty" type="xs:boolean" use="optional" default="false">
<xs:annotation>
<xs:documentation>
<![CDATA[Shorten empty elements to <tag/> instead of <tag></tag>.]]>
</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="JqArgument">
<xs:annotation>
<xs:documentation>
Arguments that will be passed to the jq script using jq's --arg parameter.
</xs:documentation>
</xs:annotation>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="name" type="xs:string" use="required" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="JqCommand">
<xs:annotation>
<xs:documentation>
Transform a JSON document using `jq`.
</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element name="arg" type="JqArgument" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="path" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>
Path to the jq script relative to the project's jq/ directory.
</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="raw-output" type="xs:boolean" default="false">
<xs:annotation>
<xs:documentation>
Enable the -r flag, causing jq to output raw strings instead of JSON strings.
</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="ShellCommand">
<xs:annotation>
<xs:documentation>
A shell command. No escaping and no controls will be made on this command, especially on spaces and newlines; use this tag with care.
</xs:documentation>
</xs:annotation>
<xs:simpleContent>
<xs:extension base="xs:string" />
</xs:simpleContent>
</xs:complexType>
<xs:group name="Command">
<xs:choice>
<xs:element name="curl" type="CurlCommand" />
<xs:element name="pup" type="PupCommand" />
<xs:element name="xml2json" type="Xml2JsonCommand" />
<xs:element name="json2xml" type="Json2XmlCommand">
<xs:unique name="xmlNamespaces">
<xs:annotation>
<xs:documentation>
XML namespace prefixes should be unique in each json2xml element.
</xs:documentation>
</xs:annotation>
<xs:selector xpath="itsb:namespace" />
<xs:field xpath="@prefix" />
</xs:unique>
</xs:element>
<xs:element name="jq" type="JqCommand">
<xs:unique name="jqArgs">
<xs:annotation>
<xs:documentation>
Argument names sent to jq should be unique.
</xs:documentation>
</xs:annotation>
<xs:selector xpath="itsb:arg" />
<xs:field xpath="@name" />
</xs:unique>
</xs:element>
<xs:element name="shell" type="ShellCommand" />
</xs:choice>
</xs:group>
<xs:simpleType name="FeedFormat">
<xs:annotation>
<xs:documentation>
Format of a syndication feed.
</xs:documentation>
</xs:annotation>
<xs:restriction base="xs:string">
<xs:enumeration value="atom" />
<xs:enumeration value="cdf" />
<xs:enumeration value="echo" />
<xs:enumeration value="json" />
<xs:enumeration value="rdf" />
<xs:enumeration value="rss" />
<xs:enumeration value="rss3" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="FeedOutput">
<xs:annotation>
<xs:documentation>
Path where the generated feed will be stored, relative to the /feeds/ directory.
</xs:documentation>
</xs:annotation>
<xs:restriction base="xs:string" />
</xs:simpleType>
<xs:complexType name="Feed">
<xs:annotation>
<xs:documentation>
<![CDATA[
A single syndication feed for this source.
Can be either generated by ITSB or provided externally.
When provided externally, only the <link> tag can be used.
]]>
</xs:documentation>
</xs:annotation>
<xs:choice>
<xs:sequence>
<xs:group ref="Command" maxOccurs="unbounded" />
<xs:element name="output" type="FeedOutput" />
</xs:sequence>
<xs:element name="link" type="URI">
<xs:annotation>
<xs:documentation>
URL to an external syndication feed.
</xs:documentation>
</xs:annotation>
</xs:element>
</xs:choice>
<xs:attribute name="lang" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>
Language of the reports in this feed. Not a language code; only for display purposes.
</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="type" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>
Report types, similar to the type tag on sources, for this particular feed.
Allows adding multiple feeds filtered by types.
When this type is omitted, the source's type can be assumed.
</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="format" type="FeedFormat" default="rss" />
<xs:attribute name="id" type="xs:ID" use="required" />
</xs:complexType>
<xs:complexType name="License">
<xs:annotation>
<xs:documentation>
A particular license that the source applies on its reports.
</xs:documentation>
</xs:annotation>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="url" type="xs:anyURI" use="optional">
<xs:annotation>
<xs:documentation>
URL pointing to an HTML page for a description of the license.
</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="Source">
<xs:annotation>
<xs:documentation>
A single source of investigation reports that can provide one or more syndication feeds.
</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string">
<xs:annotation>
@ -96,272 +379,31 @@
</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="license" minOccurs="0">
<xs:annotation>
<xs:documentation>
A particular license that the source applies on its reports.
</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="url" type="xs:anyURI" use="optional">
<xs:annotation>
<xs:documentation>
URL pointing to an HTML page for a description of the license.
</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="feed" minOccurs="1" maxOccurs="unbounded">
<xs:annotation>
<xs:documentation>
<![CDATA[
A single syndication feed for this source.
Can be either generated by ITSB or provided externally.
When provided externally, only the <link> tag can be used.
]]>
</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:choice>
<xs:sequence>
<xs:choice maxOccurs="unbounded">
<xs:element name="curl">
<xs:complexType>
<xs:sequence>
<xs:element name="url" type="itsbURL">
<xs:annotation>
<xs:documentation>
URL of the original HTML webpage that will be retrieved to be converted into a feed.
</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="header" minOccurs="0" maxOccurs="unbounded">
<xs:annotation>
<xs:documentation>
HTTP headers sent along with the request.
</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="name" type="xs:string" use="required" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="requestBody" type="xs:string" minOccurs="0">
<xs:annotation>
<xs:documentation>
Optional request body sent along with the request. When this element is used, the request becomes a POST request.
</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="license" type="License" minOccurs="0" />
<xs:element name="feed" type="Feed" minOccurs="1" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="id" type="xs:ID" use="required" />
</xs:complexType>
</xs:element>
<xs:element name="pup">
<xs:annotation>
<xs:documentation>
CSS 3 selector that will be applied using pup on the HTML webpage. The JSON output mode will be applied automatically.
If omitted, the JSON output is not applied and the downloaded content is sent directly to the script without any preprocessing.
</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="output" use="optional" default="json">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="json">
<xs:annotation>
<xs:documentation>Output the selected tags as JSON (default).</xs:documentation>
</xs:annotation>
</xs:enumeration>
<xs:enumeration value="text">
<xs:annotation>
<xs:documentation>Output the selected tags' inner text.</xs:documentation>
</xs:annotation>
</xs:enumeration>
<xs:enumeration value="html">
<xs:annotation>
<xs:documentation>Output the selected tags as HTML.</xs:documentation>
</xs:annotation>
</xs:enumeration>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="xml2json">
<xs:annotation>
<xs:documentation>
Run XML to JSON conversion using xmltodict.
</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="json2xml">
<xs:annotation>
<xs:documentation>
Run JSON to XML conversion using xmltodict.
</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element name="namespace" minOccurs="0" maxOccurs="unbounded">
<xs:annotation>
<xs:documentation>
Add an XML namespace abbreviation to be recognized by xmltodict.
</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:anyURI">
<xs:attribute name="prefix" type="xs:string" use="optional" default="">
<xs:annotation>
<xs:documentation>
The namespace prefix to use in the XML output. When not defined, this will become the default prefix (xmlns).
</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="short-empty" type="xs:boolean" use="optional" default="false">
<xs:annotation>
<xs:documentation>
<![CDATA[Shorten empty elements to <tag/> instead of <tag></tag>.]]>
</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:unique name="xmlNamespaces">
<xs:annotation>
<xs:documentation>
XML namespace prefixes should be unique in each json2xml element.
</xs:documentation>
</xs:annotation>
<xs:selector xpath="itsb:namespace" />
<xs:field xpath="@prefix" />
</xs:unique>
</xs:element>
<xs:element name="jq">
<xs:complexType>
<xs:sequence>
<xs:element name="arg" minOccurs="0" maxOccurs="unbounded">
<xs:annotation>
<xs:documentation>
Arguments that will be passed to the jq script using jq's --arg parameter.
</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="name" type="xs:string" use="required" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="path" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>
Path to the jq script relative to the project's jq/ directory.
</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="raw-output" type="xs:boolean" default="false">
<xs:annotation>
<xs:documentation>
Enable the -r flag, causing jq to output raw strings instead of JSON strings.
</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:unique name="jqArgs">
<xs:annotation>
<xs:documentation>
Argument names sent to jq should be unique.
</xs:documentation>
</xs:annotation>
<xs:selector xpath="itsb:arg" />
<xs:field xpath="@name" />
</xs:unique>
</xs:element>
<xs:element name="shell">
<xs:annotation>
<xs:documentation>
A shell command. No escaping and no controls will be made on this command, especially on spaces and newlines; use this tag with care.
</xs:documentation>
</xs:annotation>
</xs:element>
</xs:choice>
<xs:element name="output" type="xs:string">
<xs:annotation>
<xs:documentation>
Path to the resulting feed, relative to the /feeds/ directory.
</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
<xs:element name="link" type="itsbURL">
<xs:simpleType name="Content">
<xs:annotation>
<xs:documentation>
URL to an external syndication feed.
Raw, encoded HTML content that should be displayed as-is in the section.
Can be ignored by machines.
</xs:documentation>
</xs:annotation>
</xs:element>
</xs:choice>
<!-- TODO: Make lang/type/format combinations unique per source -->
<xs:attribute name="lang" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>
Language of the reports in this feed. Not a language code; only for display purposes.
</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="type" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>
Report types, similar to the type tag on sources, for this particular feed.
Allows adding multiple feeds filtered by types.
When this type is omitted, the source's type can be assumed.
</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="format" default="rss">
<xs:annotation>
<xs:documentation>
Format of the syndication feed.
</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="atom" />
<xs:enumeration value="cdf" />
<xs:enumeration value="echo" />
<xs:enumeration value="json" />
<xs:enumeration value="rdf" />
<xs:enumeration value="rss" />
<xs:enumeration value="rss3" />
</xs:restriction>
<xs:restriction base="xs:string" />
</xs:simpleType>
</xs:attribute>
<xs:attribute name="id" type="xs:ID" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="id" type="xs:ID" use="required" />
</xs:complexType>
<xs:complexType name="Section">
<xs:annotation>
<xs:documentation>
A separate section displayed in an HTML directory.
</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element name="content" type="Content" minOccurs="0" maxOccurs="unbounded" />
<xs:element name="source" type="Source" minOccurs="0" maxOccurs="unbounded">
<xs:unique name="uniqueFeedAttributes">
<xs:annotation>
<xs:documentation>
@ -383,10 +425,23 @@
</xs:attribute>
<xs:attribute name="id" type="xs:ID" use="required" />
</xs:complexType>
</xs:element>
<xs:complexType name="Document">
<xs:annotation>
<xs:documentation>
ITSB documents describe both the structure for the directory page of ITSB
and the list of syndication feeds either inventoried or generated by ITSB.
This is meant to be used as a central place to hold feed configuration and
reduce duplication.
</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element name="section" type="Section" minOccurs="1" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="version" use="required" fixed="1.0" />
</xs:complexType>
<xs:element name="itsb" type="Document">
<xs:unique name="uniqueOutputs">
<xs:annotation>
<xs:documentation>