# DMSData XML Format

The DMSData format is the primary XML format for importing, exporting, and processing objects in enaio®.
It is used by the XML import jobs of the DMS engine as input and output format.

The corresponding schema file is `DMSData.xsd`.

## Usage

The DMSData format is used by the following jobs:

| Job | Usage |
|---|---|
| [dms.XMLInsert](../dms.md#dms.XMLInsert) | Insert new object (folder, register, document) |
| [dms.XMLUpdate](../dms.md#dms.XMLUpdate) | Update field contents of an existing object |
| [dms.XMLDelete](../dms.md#dms.XMLDelete) | Delete object |
| [dms.XMLCopy](../dms.md#dms.XMLCopy) | Copy object |
| [dms.XMLMove](../dms.md#dms.XMLMove) | Move object |
| [dms.XMLImport](../dms.md#dms.XMLImport) | Process objects via the import agent |
| [dms.XMLUnknownToKnown](../dms.md#dms.XMLUnknownToKnown) | Assign typeless document to an object type |

## XML Structure

The hierarchical structure of the DMSData format:

```xml
<DMSData query_language="0">
  <Archive id="-1" name="" internal_name="" osguid="">
    <ObjectType type="FOLDER|REGISTER|DOCUMENT"
                id="-1" maintype="-1" cotype="-1" table=""
                name="" internal_name="" osguid="">
      <Object object_id="-1"
              folder_id="-1" folder_type="-1"
              register_id="-1" register_type="-1"
              maintype="-1" concurrency_timestamp="-1"
              variantparent_id="-1"
              sourceparent_id="-1" target_type="-1">

        <!-- Search conditions (optional, for Query operations) -->
        <Search>
          <Fields>
            <Field name="" internal_name="" dbname="" osguid=""
                   system="0" field_function="">Value</Field>
          </Fields>
          <TableFields>
            <TableField name="" internal_name="" dbname="">
              <Field name="" internal_name="" dbname="">Value</Field>
            </TableField>
          </TableFields>
          <MultiFields>
            <Field name="" internal_name="" dbname="">Value</Field>
          </MultiFields>
        </Search>

        <!-- Simple fields -->
        <Fields>
          <Field name="" internal_name="" dbname="" osguid=""
                 system="0" field_function="">Value</Field>
        </Fields>

        <!-- Multi-fields -->
        <MultiFields>
          <MultiField name="" internal_name="" dbname="">
            <Page id="1">
              <Value>Value1</Value>
              <Value>Value2</Value>
            </Page>
          </MultiField>
        </MultiFields>

        <!-- Table fields (Mode 1: row-wise) -->
        <TableFields>
          <TableField name="" internal_name="" dbname="">
            <Row line="-1">
              <Field name="" internal_name="" dbname="">Value</Field>
            </Row>
          </TableField>
        </TableFields>

        <!-- Table fields (Mode 2: column/row result) -->
        <TableFields>
          <TableField name="" internal_name="" dbname="">
            <Columns>
              <Column name="" internal_name="" dbname="">Column Title</Column>
            </Columns>
            <Rows>
              <Row line="-1">
                <Value field_function="">Value</Value>
              </Row>
            </Rows>
          </TableField>
        </TableFields>

        <!-- Remarks -->
        <Remarks>
          <RemarkText action="INSERT" remark_id="" color="WHITE">Note text</RemarkText>
          <RemarkObject action="INSERT" object_id="123" object_type="4" color="WHITE"/>
        </Remarks>

      </Object>
    </ObjectType>
  </Archive>
</DMSData>
```

## Elements and Attributes

### `<DMSData>` (root element)

| Attribute | Type | Default | Description |
|---|---|---|---|
| `query_language` | xs:long | `0` | Reserved. Must be `0`. |

### `<Archive>`

Identifies the enaio® archive in which the operation is performed.
At least one of the attributes `id`, `name`, `internal_name` or `osguid` must be specified.

| Attribute | Type | Default | Description |
|---|---|---|---|
| `id` | xs:long | `-1` | Numeric archive ID |
| `name` | xs:string | — | Display name of the archive |
| `internal_name` | xs:string | — | Internal (technical) name of the archive |
| `osguid` | xs:string | — | GUID of the archive |

### `<ObjectType>`

Identifies the object type within the archive.

| Attribute | Type | Default | Description |
|---|---|---|---|
| `type` | <<objecttypes,objecttypes>> | — | Type of the object: `FOLDER`, `REGISTER` or `DOCUMENT` |
| `id` | xs:long | `-1` | Numeric ID of the object type. Structure: Object Type ID. |
| `maintype` | xs:short | `-1` | Main type of the object type. Value range: Object Type ID. |
| `cotype` | xs:short | `-1` | Subtype of the object type (lowword of the object type ID). |
| `table` | xs:string | — | Database table name of the object type |
| `name` | xs:string | — | Display name of the object type |
| `internal_name` | xs:string | — | Internal (technical) name of the object type |
| `osguid` | xs:string | — | GUID of the object type |

### `<Object>`

Describes the concrete object instance. Contains information about the object's location and its field contents.

| Attribute | Type | Default | Description |
|---|---|---|---|
| `object_id` | xs:long | `-1` | ID of the object instance (required for Update/Delete/Copy/Move) |
| `folder_id` | xs:long | `-1` | ID of the parent folder (required for Insert of registers/documents) |
| `folder_type` | xs:long | `-1` | Type of the parent folder |
| `register_id` | xs:long | `-1` | ID of the parent register (required for Insert of documents) |
| `register_type` | xs:long | `-1` | Type of the parent register |
| `maintype` | xs:long | `-1` | Main type of the document. Values and meaning: Object Type ID. |
| `concurrency_timestamp` | xs:long | `-1` | Timestamp for conflict detection during concurrent updates |
| `variantparent_id` | xs:long | `-1` | ID of the parent object for variant documents |
| `sourceparent_id` | xs:long | `-1` | ID of the source object (for Copy/Move operations) |
| `target_type` | xs:long | `-1` | Target type (for Copy/Move operations) |

### `<Search>`

Optional section within `<Object>` for search conditions in Query operations.
Contains the same sub-elements as `<Object>` itself (`<Fields>`, `<TableFields>`, `<MultiFields>`),
but exclusively for specifying search conditions.

### `<Fields>` / `<Field>`

`<Fields>` contains a list of `<Field>` elements for simple fields.

| Attribute | Type | Default | Description |
|---|---|---|---|
| Text content | xs:string | — | Field value |
| `name` | xs:string | — | Display name of the field |
| `internal_name` | xs:string | — | Internal (technical) name of the field |
| `dbname` | xs:string | — | Database column name of the field |
| `osguid` | xs:string | — | GUID of the field |
| `system` | xs:short | `0` | System field indicator (`1` = system field) |
| `field_function` | <<fieldfunctiontypes,fieldfunctiontypes>> | — | Special field function: `NULL`, `OBJECT_ID` or `USER` |
> **Note:** At least one of the attributes `name`, `internal_name`, `dbname` or `osguid` must be specified to identify the field. `internal_name` is recommended.

### `<TableFields>` / `<TableField>`

`<TableFields>` contains a list of `<TableField>` elements for table fields (Grid controls).
Each `<TableField>` is identified by `field_ident` attributes (like `<Field>`) and can appear in two modes:

#### Mode 1 — Row-wise (`<Row>`)

Used for **write operations** (Insert/Update). Each row contains field values as `<Field>` elements.

```xml
<TableFields>
  <TableField internal_name="invoice_positions">
    <Row line="-1">
      <Field internal_name="pos_number">1</Field>
      <Field internal_name="pos_description">Consultation service</Field>
      <Field internal_name="pos_amount">1200.00</Field>
    </Row>
    <Row line="-1">
      <Field internal_name="pos_number">2</Field>
      <Field internal_name="pos_description">Travel expenses</Field>
      <Field internal_name="pos_amount">350.00</Field>
    </Row>
  </TableField>
</TableFields>
```
The `line` attribute of `<Row>` specifies the 1-based row number whose values should be changed during update operations. `-1` stands for a new row (Append).

`<Field>` within `<Row>` supports the attributes `name`, `internal_name`, `dbname`, `osguid` and `field_function` (no `system`).

#### Mode 2 — Columns/Rows (`<Columns>` + `<Rows>`)

Used for **read results** (Query responses). The column structure is described separately from the data rows.

```xml
<TableFields>
  <TableField internal_name="invoice_positions">
    <Columns>
      <Column internal_name="pos_number">Pos. No.</Column>
      <Column internal_name="pos_description">Description</Column>
      <Column internal_name="pos_amount">Amount</Column>
    </Columns>
    <Rows>
      <Row line="1">
        <Value>1</Value>
        <Value>Consultation service</Value>
        <Value>1200.00</Value>
      </Row>
    </Rows>
  </TableField>
</TableFields>
```
`<Column>` supports the attributes `name`, `internal_name`, `dbname`.
`<Value>` within `<Rows>/<Row>` supports the attribute `field_function` (<<fieldfunctiontypes,fieldfunctiontypes>>).

### `<MultiFields>` / `<MultiField>`

`<MultiFields>` contains a list of `<MultiField>` elements for multi-fields.
Each `<MultiField>` contains `<Page>` elements (pages/instances) that carry multiple `<Value>` entries.

| Attribute | Type | Required | Description |
|---|---|---|---|
| `id` (on `<Page>`) | xs:long | Yes | Page ID (1-based) |
```xml
<MultiFields>
  <MultiField internal_name="keywords">
    <Page id="1">
      <Value>Invoice</Value>
      <Value>2024</Value>
    </Page>
  </MultiField>
</MultiFields>
```

### `<Remarks>`

Contains notes associated with the object. Each note is either a text note (`<RemarkText>`) or an object reference (`<RemarkObject>`).

#### `<RemarkText>`

| Attribute | Type | Default | Description |
|---|---|---|---|
| Text content | xs:string | — | Text of the note |
| `action` | <<remarkactiontypes,remarkactiontypes>> | `INSERT` | Action to perform |
| `remark_id` | xs:integer | — | ID of the note (required for UPDATE/DELETE) |
| `color` | <<remarkcolortypes,remarkcolortypes>> | `WHITE` | Background color of the note |

#### `<RemarkObject>`

| Attribute | Type | Default | Description |
|---|---|---|---|
| Text content | xs:string | — | Optional description text |
| `action` | <<remarkactiontypes,remarkactiontypes>> | `INSERT` | Action to perform |
| `object_id` | xs:integer | Required | ID of the referenced object |
| `object_type` | xs:integer | Required | Type of the referenced object (object type ID, see Object Type ID). |
| `color` | <<remarkcolortypes,remarkcolortypes>> | `WHITE` | Background color of the note |

## Enumeration Types

### `objecttypes`

| Value | Meaning |
|---|---|
| `FOLDER` | Folder |
| `REGISTER` | Register |
| `DOCUMENT` | Document |

### `fieldfunctiontypes`

Controls the interpretation of the field value for certain system fields.

| Value | Meaning |
|---|---|
| `NULL` | Explicitly set field value to NULL |
| `OBJECT_ID` | Field value is an object ID |
| `USER` | Field value is a username |

### `remarkactiontypes`

| Value | Meaning |
|---|---|
| `INSERT` | Create new note |
| `UPDATE` | Update text and color of the note |
| `UPDATE_TEXT` | Update only the text of the note |
| `UPDATE_COLOR` | Update only the color of the note |
| `DELETE` | Delete note |

### `remarkcolortypes`

| Value | Meaning |
|---|---|
| `WHITE` | White (default) |
| `YELLOW` | Yellow |
| `GREEN` | Green |
| `BLUE` | Blue |

## Examples

### Insert document (dms.XMLInsert)

A new document is inserted into a known register. Archive, object type, parent register and field values are specified.

```xml
<DMSData>
  <Archive internal_name="patient">
    <ObjectType type="DOCUMENT" internal_name="medical_letter">
      <Object register_id="4711" register_type="12" maintype="4">
        <Fields>
          <Field internal_name="date">2024-03-15</Field>
          <Field internal_name="subject">Discharge letter</Field>
          <Field internal_name="physician">Dr. Müller</Field>
        </Fields>
      </Object>
    </ObjectType>
  </Archive>
</DMSData>
```

### Update fields of an object (dms.XMLUpdate)

An existing object is identified by its `object_id` and individual fields are updated.

```xml
<DMSData>
  <Archive internal_name="patient">
    <ObjectType type="DOCUMENT" internal_name="medical_letter">
      <Object object_id="9823">
        <Fields>
          <Field internal_name="subject">Discharge letter (corrected)</Field>
        </Fields>
      </Object>
    </ObjectType>
  </Archive>
</DMSData>
```

### Delete object (dms.XMLDelete)

An object is deleted by its `object_id`. Fields do not need to be specified.

```xml
<DMSData>
  <Archive internal_name="patient">
    <ObjectType type="DOCUMENT" internal_name="medical_letter">
      <Object object_id="9823"/>
    </ObjectType>
  </Archive>
</DMSData>
```

### Fill table field with multiple rows (dms.XMLInsert)

```xml
<DMSData>
  <Archive internal_name="accounting">
    <ObjectType type="DOCUMENT" internal_name="invoice">
      <Object register_id="100" register_type="5" maintype="4">
        <Fields>
          <Field internal_name="invoice_number">2024-0042</Field>
          <Field internal_name="invoice_date">2024-03-15</Field>
        </Fields>
        <TableFields>
          <TableField internal_name="positions">
            <Row>
              <Field internal_name="pos_nr">1</Field>
              <Field internal_name="description">Consultation</Field>
              <Field internal_name="net_amount">1200.00</Field>
            </Row>
            <Row>
              <Field internal_name="pos_nr">2</Field>
              <Field internal_name="description">Travel expenses</Field>
              <Field internal_name="net_amount">350.00</Field>
            </Row>
          </TableField>
        </TableFields>
      </Object>
    </ObjectType>
  </Archive>
</DMSData>
```

### Set field to NULL (dms.XMLUpdate)

The `field_function` value `NULL` instructs the server to explicitly delete the field content.

```xml
<DMSData>
  <Archive internal_name="patient">
    <ObjectType type="DOCUMENT" internal_name="medical_letter">
      <Object object_id="9823">
        <Fields>
          <Field internal_name="physician" field_function="NULL"/>
        </Fields>
      </Object>
    </ObjectType>
  </Archive>
</DMSData>
```
