[Feature] Minimal IUCLID export (#338)

This is an initial implementation that creates a working minimal .i6z document.
It passes schema validation and can be imported into IUCLID.

Caveat:
IUCLID files target individual compounds.
Pathway is not actually covered by the format.

It can be added in either soil or water and soil OECD endpoints.
**I currently only implemented the soil endpoint for all data.**

This sort of works, and I can report all degradation products in a pathway (not a nice view, but we can report many transformation products and add a diagram attachment in the future).

Adding additional information is an absolute pain, as we need to explicitly map each type of information to the relevant OECD field.
I use the XSD scheme for validation, but unfortunately the IUCLID parser is not fully compliant and requires a specific order, etc.

The workflow is: finding the AI structure from the XSD scheme -> make the scheme validation pass -> upload to IUCLID to get obscure error messages -> guess what could be wrong -> repeat 💣

New specifications get released once per year, so we will have to update accordingly.
I believe that this should be a more expensive feature, as it requires significant effort to uphold.

Currently implemented for root compound only in SOIL:

- Soil Texture 2
- Soil Texture 1
- pH value
- Half-life per soil sample / scenario (mapped to disappearance; not sure about that).
- CEC
- Organic Matter (only Carbon)
- Moisture content
- Humidity

<img width="2123" alt="image.png" src="attachments/d29830e1-65ef-4136-8939-1825e0959c62">
<img width="2124" alt="image.png" src="attachments/ac9de2ac-bf68-4ba4-b40b-82f810a9de93">
<img width="2139" alt="image.png" src="attachments/5674c7e6-865e-420e-974a-6b825b331e6c">

Reviewed-on: enviPath/enviPy#338
Co-authored-by: Tobias O <tobias.olenyi@envipath.com>
Co-committed-by: Tobias O <tobias.olenyi@envipath.com>
This commit is contained in:
2026-04-07 19:46:12 +12:00
committed by jebus
parent f7c45b8015
commit d06bd0d4fd
49 changed files with 66402 additions and 1014 deletions

View File

@ -0,0 +1,231 @@
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xlink="http://www.w3.org/1999/xlink" targetNamespace="http://www.w3.org/1999/xlink">
<xs:annotation>
<xs:documentation>
This schema document provides attribute declarations and attribute
group, complex type and simple type definitions which can be used in
the construction of user schemas to define the structure of
particular linking constructs, e.g.
<![CDATA[
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xl="http://www.w3.org/1999/xlink">
<xs:import namespace="http://www.w3.org/1999/xlink"
location="http://www.w3.org/1999/xlink.xsd">
<xs:element name="mySimple">
<xs:complexType>
...
<xs:attributeGroup ref="xl:simpleAttrs"/>
...
</xs:complexType>
</xs:element>
...
</xs:schema>
]]>
</xs:documentation>
</xs:annotation>
<xs:import namespace="http://www.w3.org/XML/1998/namespace"
schemaLocation="xml.xsd" />
<xs:attribute name="type" type="xlink:typeType" />
<xs:simpleType name="typeType">
<xs:restriction base="xs:token">
<xs:enumeration value="simple" />
<xs:enumeration value="extended" />
<xs:enumeration value="title" />
<xs:enumeration value="resource" />
<xs:enumeration value="locator" />
<xs:enumeration value="arc" />
</xs:restriction>
</xs:simpleType>
<xs:attribute name="href" type="xlink:hrefType" />
<xs:simpleType name="hrefType">
<xs:restriction base="xs:anyURI" />
</xs:simpleType>
<xs:attribute name="role" type="xlink:roleType" />
<xs:simpleType name="roleType">
<xs:restriction base="xs:anyURI">
<xs:minLength value="1" />
</xs:restriction>
</xs:simpleType>
<xs:attribute name="arcrole" type="xlink:arcroleType" />
<xs:simpleType name="arcroleType">
<xs:restriction base="xs:anyURI">
<xs:minLength value="1" />
</xs:restriction>
</xs:simpleType>
<xs:attribute name="title" type="xlink:titleAttrType" />
<xs:simpleType name="titleAttrType">
<xs:restriction base="xs:string" />
</xs:simpleType>
<xs:attribute name="show" type="xlink:showType" />
<xs:simpleType name="showType">
<xs:restriction base="xs:token">
<xs:enumeration value="new" />
<xs:enumeration value="replace" />
<xs:enumeration value="embed" />
<xs:enumeration value="other" />
<xs:enumeration value="none" />
</xs:restriction>
</xs:simpleType>
<xs:attribute name="actuate" type="xlink:actuateType" />
<xs:simpleType name="actuateType">
<xs:restriction base="xs:token">
<xs:enumeration value="onLoad" />
<xs:enumeration value="onRequest" />
<xs:enumeration value="other" />
<xs:enumeration value="none" />
</xs:restriction>
</xs:simpleType>
<xs:attribute name="label" type="xlink:labelType" />
<xs:simpleType name="labelType">
<xs:restriction base="xs:NCName" />
</xs:simpleType>
<xs:attribute name="from" type="xlink:fromType" />
<xs:simpleType name="fromType">
<xs:restriction base="xs:NCName" />
</xs:simpleType>
<xs:attribute name="to" type="xlink:toType" />
<xs:simpleType name="toType">
<xs:restriction base="xs:NCName" />
</xs:simpleType>
<xs:attributeGroup name="simpleAttrs">
<xs:attribute ref="xlink:type" fixed="simple" />
<xs:attribute ref="xlink:href" />
<xs:attribute ref="xlink:role" />
<xs:attribute ref="xlink:arcrole" />
<xs:attribute ref="xlink:title" />
<xs:attribute ref="xlink:show" />
<xs:attribute ref="xlink:actuate" />
</xs:attributeGroup>
<xs:group name="simpleModel">
<xs:sequence>
<xs:any processContents="lax" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:group>
<xs:complexType mixed="true" name="simple">
<xs:annotation>
<xs:documentation>
Intended for use as the type of user-declared elements to make them simple
links.
</xs:documentation>
</xs:annotation>
<xs:group ref="xlink:simpleModel" />
<xs:attributeGroup ref="xlink:simpleAttrs" />
</xs:complexType>
<xs:attributeGroup name="extendedAttrs">
<xs:attribute ref="xlink:type" fixed="extended" use="required" />
<xs:attribute ref="xlink:role" />
<xs:attribute ref="xlink:title" />
</xs:attributeGroup>
<xs:group name="extendedModel">
<xs:choice>
<xs:element ref="xlink:title" />
<xs:element ref="xlink:resource" />
<xs:element ref="xlink:locator" />
<xs:element ref="xlink:arc" />
</xs:choice>
</xs:group>
<xs:complexType name="extended">
<xs:annotation>
<xs:documentation>
Intended for use as the type of user-declared elements to make them extended
links. Note that the elements referenced in the content model are
all abstract. The intention is that by simply declaring elements
with these as their substitutionGroup, all the right things will
happen.
</xs:documentation>
</xs:annotation>
<xs:group ref="xlink:extendedModel" minOccurs="0" maxOccurs="unbounded" />
<xs:attributeGroup ref="xlink:extendedAttrs" />
</xs:complexType>
<xs:element name="title" type="xlink:titleEltType" abstract="true" />
<xs:attributeGroup name="titleAttrs">
<xs:attribute ref="xlink:type" fixed="title" use="required" />
<xs:attribute ref="xml:lang">
<xs:annotation>
<xs:documentation>
xml:lang is not required, but provides much of the motivation for title
elements in addition to attributes, and so is provided here for
convenience.
</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:attributeGroup>
<xs:group name="titleModel">
<xs:sequence>
<xs:any processContents="lax" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:group>
<xs:complexType mixed="true" name="titleEltType">
<xs:group ref="xlink:titleModel" />
<xs:attributeGroup ref="xlink:titleAttrs" />
</xs:complexType>
<xs:element name="resource" type="xlink:resourceType"
abstract="true" />
<xs:attributeGroup name="resourceAttrs">
<xs:attribute ref="xlink:type" fixed="resource" use="required" />
<xs:attribute ref="xlink:role" />
<xs:attribute ref="xlink:title" />
<xs:attribute ref="xlink:label" />
</xs:attributeGroup>
<xs:group name="resourceModel">
<xs:sequence>
<xs:any processContents="lax" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:group>
<xs:complexType mixed="true" name="resourceType">
<xs:group ref="xlink:resourceModel" />
<xs:attributeGroup ref="xlink:resourceAttrs" />
</xs:complexType>
<xs:element name="locator" type="xlink:locatorType"
abstract="true" />
<xs:attributeGroup name="locatorAttrs">
<xs:attribute ref="xlink:type" fixed="locator" use="required" />
<xs:attribute ref="xlink:href" use="required" />
<xs:attribute ref="xlink:role" />
<xs:attribute ref="xlink:title" />
<xs:attribute ref="xlink:label">
<xs:annotation>
<xs:documentation>
label is not required, but locators have no particular XLink function if
they are not labeled.
</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:attributeGroup>
<xs:group name="locatorModel">
<xs:sequence>
<xs:element ref="xlink:title" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:group>
<xs:complexType name="locatorType">
<xs:group ref="xlink:locatorModel" />
<xs:attributeGroup ref="xlink:locatorAttrs" />
</xs:complexType>
<xs:element name="arc" type="xlink:arcType" abstract="true" />
<xs:attributeGroup name="arcAttrs">
<xs:attribute ref="xlink:type" fixed="arc" use="required" />
<xs:attribute ref="xlink:arcrole" />
<xs:attribute ref="xlink:title" />
<xs:attribute ref="xlink:show" />
<xs:attribute ref="xlink:actuate" />
<xs:attribute ref="xlink:from" />
<xs:attribute ref="xlink:to">
<xs:annotation>
<xs:documentation>
from and to have default behavior when values are missing
</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:attributeGroup>
<xs:group name="arcModel">
<xs:sequence>
<xs:element ref="xlink:title" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:group>
<xs:complexType name="arcType">
<xs:group ref="xlink:arcModel" />
<xs:attributeGroup ref="xlink:arcAttrs" />
</xs:complexType>
</xs:schema>