183 lines
15 KiB
Markdown
183 lines
15 KiB
Markdown
|
|
---
|
|||
|
|
source_files:
|
|||
|
|
- Common/DTS.Common.Import/XML/XMLPre20ParseGroupTemplates.cs
|
|||
|
|
- Common/DTS.Common.Import/XML/XMLParseMMECustomDirections.cs
|
|||
|
|
- Common/DTS.Common.Import/XML/XMLParseMMECustomTestObjects.cs
|
|||
|
|
- Common/DTS.Common.Import/XML/XMLParseMMECustomPositions.cs
|
|||
|
|
- Common/DTS.Common.Import/XML/XMLParseMMECustomFineLoc3s.cs
|
|||
|
|
- Common/DTS.Common.Import/XML/XMLParseMMECustomFineLoc2s.cs
|
|||
|
|
- Common/DTS.Common.Import/XML/XMLParseMMECustomFineLoc1s.cs
|
|||
|
|
- Common/DTS.Common.Import/XML/XMLParseSensorModels.cs
|
|||
|
|
- Common/DTS.Common.Import/XML/XMLParseMMECustomFilterClasses.cs
|
|||
|
|
- Common/DTS.Common.Import/XML/XMLParseMMECustomChannels.cs
|
|||
|
|
- Common/DTS.Common.Import/XML/XMLParseMMECustomMainLocations.cs
|
|||
|
|
- Common/DTS.Common.Import/XML/XMLParseMMECustomPhysicalDimensions.cs
|
|||
|
|
- Common/DTS.Common.Import/XML/XMLPre20ParseSensors.cs
|
|||
|
|
- Common/DTS.Common.Import/XML/XMLParseUsers.cs
|
|||
|
|
- Common/DTS.Common.Import/XML/XMLParseBase.cs
|
|||
|
|
- Common/DTS.Common.Import/XML/XMLParseTestEngineerDetails.cs
|
|||
|
|
- Common/DTS.Common.Import/XML/XMLParseLabDetails.cs
|
|||
|
|
- Common/DTS.Common.Import/XML/XMLParseGlobalSettings.cs
|
|||
|
|
- Common/DTS.Common.Import/XML/XMLPre20ParseDASList.cs
|
|||
|
|
- Common/DTS.Common.Import/XML/XMLParseCustomerDetails.cs
|
|||
|
|
- Common/DTS.Common.Import/XML/XMLParseSensors.cs
|
|||
|
|
- Common/DTS.Common.Import/XML/XMLParseDASList.cs
|
|||
|
|
- Common/DTS.Common.Import/XML/XMLParseGroupTemplates.cs
|
|||
|
|
- Common/DTS.Common.Import/XML/XMLParseCalibrations.cs
|
|||
|
|
- Common/DTS.Common.Import/XML/XMLPre20ParseCalibrations.cs
|
|||
|
|
- Common/DTS.Common.Import/XML/XMLParseGroups.cs
|
|||
|
|
- Common/DTS.Common.Import/XML/XMLParseTestSetups.cs
|
|||
|
|
generated_at: "2026-04-16T02:07:16.226597+00:00"
|
|||
|
|
model: "Qwen/Qwen3-Coder-Next-FP8"
|
|||
|
|
schema_version: 1
|
|||
|
|
sha256: "87dec39982bd8179"
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# XML Import Parsers Module Documentation
|
|||
|
|
|
|||
|
|
## 1. Purpose
|
|||
|
|
|
|||
|
|
This module provides a family of XML parsing classes responsible for deserializing versioned XML export files into the system’s in-memory `ImportObject` representation during data import operations. Each concrete parser targets a specific data domain (e.g., sensors, groups, channels, test setups, calibration data, MME custom objects) and handles both direct parsing and migration logic for pre-2.0 XML formats. These parsers implement the `IParseVariant` interface, inherit from `XMLParseBase`, and coordinate with other parsers (e.g., via constructor injection) to resolve cross-references and normalize identifiers across related entities. The module serves as the core deserialization layer for backward-compatible XML imports, ensuring robust handling of schema evolution and data integrity constraints.
|
|||
|
|
|
|||
|
|
## 2. Public Interface
|
|||
|
|
|
|||
|
|
All classes inherit from `XMLParseBase` and implement the abstract method `Parse(ref ImportObject importObject)`. Below are the public classes and their key behaviors.
|
|||
|
|
|
|||
|
|
### `XMLParseBase`
|
|||
|
|
- **Constructor**: `XMLParseBase(XmlElement root, double importedVersion, Func<bool> isCancelled = null, bool skipNormalizing = false)`
|
|||
|
|
- Stores the XML root node, imported file version, cancellation token, and normalization flag.
|
|||
|
|
- Initializes internal XML writer and mapping dictionaries (`_dasIdMapping`, `_groupIdMapping`, `_sensorIdMapping`, `_channelIdMapping`) for cross-entity ID normalization.
|
|||
|
|
- **Protected Methods**:
|
|||
|
|
- `XmlElement GetXmlElement()` – Finalizes XML writing and returns the constructed `XmlElement`.
|
|||
|
|
- `bool IsCancelled()` – Invokes the cancellation token (defaults to `() => false`).
|
|||
|
|
|
|||
|
|
### `XMLParseSensors`
|
|||
|
|
- **Constructor**: `XMLParseSensors(XmlElement root, double importedVersion, Func<bool> isCancelled = null, bool skipNormalizing = false)`
|
|||
|
|
- **Public Methods**:
|
|||
|
|
- `XmlElement ConvertSensors(IEnumerable<SensorData> sensors)` – Normalizes sensor `DatabaseId`s (assigns negative IDs starting at -2), updates `_sensorIdMapping`, and writes normalized XML.
|
|||
|
|
- `IEnumerable<SensorData> ParseSensors(XmlElement root)` – Parses `SensorData` objects from XML nodes; skips non-`XmlElement` nodes.
|
|||
|
|
|
|||
|
|
### `XMLPre20ParseSensors`
|
|||
|
|
- **Constructor**: `XMLPre20ParseSensors(XmlElement root, double importedVersion, XMLParseSensors xmlParseSensors, Func<bool> isCancelled = null)`
|
|||
|
|
- **Public Methods**:
|
|||
|
|
- `XmlElement MigrateSensors(IEnumerable<SensorData> sensors)` – Migrates pre-2.0 sensor data by assigning negative `DatabaseId`s (starting at -1) and writing to XML.
|
|||
|
|
- **Behavior**: Parses sensors, migrates them to the new schema, then delegates to `_xmlParseSensors.ParseSensors()` for final parsing.
|
|||
|
|
|
|||
|
|
### `XMLParseDASList`
|
|||
|
|
- **Constructor**: `XMLParseDASList(XmlElement root, double importedVersion, Func<bool> isCancelled = null, bool skipNormalizing = false)`
|
|||
|
|
- **Public Methods**:
|
|||
|
|
- `List<DASHardware> ParseDASList(XmlElement root)` – Parses `DASHardware` objects; filters out entries with invalid `DASType` (logs serial numbers to `invalidDAS` list, but does not report errors).
|
|||
|
|
- `XmlElement ConvertDASList(List<DASHardware> dasList)` – Normalizes `DASId`s (starting at -2) and updates `_dasIdMapping`.
|
|||
|
|
- **Behavior**: On import, validates `DASType` enum values; skips invalid entries silently.
|
|||
|
|
|
|||
|
|
### `XMLPre20ParseDASList`
|
|||
|
|
- **Constructor**: `XMLPre20ParseDASList(XmlElement root, double importedVersion, XMLParseDASList xmlParseDASList, Func<bool> isCancelled = null)`
|
|||
|
|
- **Public Methods**:
|
|||
|
|
- `List<DASHardware> ParsePre20DASList(XmlElement root)` – Parses pre-2.0 `DASHardware` objects.
|
|||
|
|
- `XmlElement MigratePre20DASList(List<DASHardware> dasList)` – Assigns negative `DASId`s (starting at -1) and writes to XML.
|
|||
|
|
- **Behavior**: Migrates pre-2.0 DAS list, then delegates to `_xmlParseDASList.ParseDASList()`.
|
|||
|
|
|
|||
|
|
### `XMLParseGroups`
|
|||
|
|
- **Constructor**: `XMLParseGroups(XmlElement root, double importedVersion, Func<bool> isCancelled = null)`
|
|||
|
|
- **Public Methods**:
|
|||
|
|
- `List<IGroup> ParseGroups(XmlElement root, ref ImportObject importObject)` – Parses groups, resolving channel references to imported sensors/DAS via lookup dictionaries. Handles both pre-2.0 (name-based) and post-2.0 (ID-based) group IDs in `_groupIdMapping`.
|
|||
|
|
- `XmlElement ConvertGroups(List<IGroup> staticGroups)` – Normalizes group `Id`s (starting at -2), DAS/sensor IDs in channels (using `_dasIdMapping`/`_sensorIdMapping`), and writes to XML. Silently sets `SensorId = 0` for deleted sensors (FB 14308).
|
|||
|
|
- **Behavior**: Normalizes group and channel IDs; handles sensor deletion gracefully.
|
|||
|
|
|
|||
|
|
### `XMLParseGroupTemplates`
|
|||
|
|
- **Constructor**: `XMLParseGroupTemplates(XmlElement root, double importedVersion, ISO.ISO13499FileDb iSO13499FileDb, Func<bool> isCancelled = null)`
|
|||
|
|
- **Public Methods**:
|
|||
|
|
- `IEnumerable<DataPROWin7.DataModel.TestObjectTemplate> ParseGroupTemplates(ref ImportObject importObject, XmlElement root)` – Parses group templates, resolving channels from `importObject.CustomChannels()`. Enforces that referenced ISO test objects exist in `importObject.TestObjects()` (throws `NotSupportedException` if missing, FB 8790).
|
|||
|
|
- **Behavior**: Requires pre-parsed custom channels and test objects; validates test object existence.
|
|||
|
|
|
|||
|
|
### `XMLParseTestSetups`
|
|||
|
|
- **Constructor**: `XMLParseTestSetups(XmlElement root, double importedVersion, Func<bool> isCancelled = null, bool skipNormalizing = false)`
|
|||
|
|
- **Public Methods**:
|
|||
|
|
- `XmlElement ConvertTestTemplates(IEnumerable<TestTemplate> testTemplates, ImportObject importObject)` – Normalizes group IDs, channel IDs (using `_groupIdMapping`, `_channelIdMapping`), and DAS/sensor IDs in channels. Handles missing static group IDs (sets to `null`) and deleted sensors (sets `SensorId = 0`, FB 14308).
|
|||
|
|
- `IEnumerable<TestTemplate> ParseTestTemplate(ImportObject importObject, XmlElement root)` – Parses test setups using lookup dictionaries for test objects, groups, customer/lab details, sensors, etc. Catches and logs parsing errors as warnings (FB 36879).
|
|||
|
|
- **Behavior**: Requires pre-parsed entities (groups, sensors, etc.) to resolve references; handles missing/invalid references gracefully.
|
|||
|
|
|
|||
|
|
### `XMLParseCalibrations`
|
|||
|
|
- **Constructor**: `XMLParseCalibrations(XmlElement root, double importedVersion, Func<bool> isCancelled = null)`
|
|||
|
|
- **Public Methods**:
|
|||
|
|
- `XmlElement ConvertCalibrations(IEnumerable<SensorCalibration> calibrations)` – Writes normalized calibration XML.
|
|||
|
|
- `IEnumerable<SensorCalibration> ParseCalibrations(XmlElement root)` – Parses calibrations with version-specific logic:
|
|||
|
|
- For `importedVersion >= DataPROPre20XmlVersion`: Direct parsing.
|
|||
|
|
- For `importedVersion == 1.0`: Sets `AtCapacity = false` and infers `SensitivityUnits` (mV/EU, mV/V/EU, or NONE) based on calibration type.
|
|||
|
|
|
|||
|
|
### `XMLPre20ParseCalibrations`
|
|||
|
|
- **Constructor**: `XMLPre20ParseCalibrations(XmlElement root, double importedVersion, XMLParseCalibrations xmlParseCalibrations, Func<bool> isCancelled = null)`
|
|||
|
|
- **Behavior**: Parses pre-2.0 calibrations, adds them to sensors via `AddToSensor()`, then delegates normalization and re-parsing to `_xmlParseCalibrations`.
|
|||
|
|
|
|||
|
|
### `XMLParseMMECustom*` Parsers (e.g., `XMLParseMMECustomChannels`, `XMLParseMMECustomPositions`, etc.)
|
|||
|
|
- **Common Pattern**:
|
|||
|
|
- **Constructor**: `XMLParseMMECustom* (XmlElement root, double importedVersion, Func<bool> isCancelled = null)`
|
|||
|
|
- **Public/Protected Methods**:
|
|||
|
|
- `ParseCustom* (XmlElement root)` – Parses a list of MME objects (e.g., `ISO.MMEPossibleChannels`, `ISO.MMEPositions`) from XML child nodes.
|
|||
|
|
- `Parse(ref ImportObject importObject)` – Adds parsed list to `importObject` via `AddCustom*()` methods.
|
|||
|
|
- **Behavior**: Iterates child `XmlElement`s, calls `ReadXML()` on each, and respects cancellation. No normalization or migration logic (assumes current-version format).
|
|||
|
|
|
|||
|
|
### `XMLPre20ParseGroupTemplates`
|
|||
|
|
- **Constructor**: `XMLPre20ParseGroupTemplates(XmlElement root, double importedVersion, XMLParseGroupTemplates xmlParseGroupTemplates, Func<bool> isCancelled = null)`
|
|||
|
|
- **Behavior**: Delegates parsing to `_xmlParseGroupTemplates.ParseGroupTemplates()`; no migration logic visible.
|
|||
|
|
|
|||
|
|
### `XMLParseUsers`
|
|||
|
|
- **Constructor**: `XMLParseUsers(XmlElement root, double importedVersion, IEnumerable<IUIItems> uiItems, Func<bool> isCancelled = null)`
|
|||
|
|
- **Behavior**: Parses `User` objects using `User.ReadXML()`, passing `uiItems` for UI context.
|
|||
|
|
|
|||
|
|
### `XMLParseTestEngineerDetails`, `XMLParseLabDetails`, `XMLParseCustomerDetails`
|
|||
|
|
- **Pattern**: Parse → Convert → Re-parse → Add to `importObject`.
|
|||
|
|
- `Parse*()` – Initial parse.
|
|||
|
|
- `Convert*()` – Writes parsed objects to XML.
|
|||
|
|
- Re-parse normalized XML to ensure consistency.
|
|||
|
|
- **Behavior**: All use `Convert*()` to normalize and re-parse; no ID mapping beyond XML structure.
|
|||
|
|
|
|||
|
|
### `XMLParseGlobalSettings`
|
|||
|
|
- **Constructor**: `XMLParseGlobalSettings(XmlElement root, double importedVersion, Func<bool> isCancelled = null)`
|
|||
|
|
- **Behavior**: Parses `<SettingName>` and `<SettingValue>` child elements into a `Dictionary<string, string>`.
|
|||
|
|
|
|||
|
|
## 3. Invariants
|
|||
|
|
|
|||
|
|
- **ID Normalization**: All parsers that normalize IDs (e.g., `XMLParseSensors`, `XMLParseDASList`, `XMLParseGroups`, `XMLParseTestSetups`) assign negative integer IDs starting at -1 or -2 (to avoid conflicts with database IDs). Mappings are stored in static dictionaries (`_sensorIdMapping`, `_dasIdMapping`, `_groupIdMapping`, `_channelIdMapping`) and used during cross-entity resolution.
|
|||
|
|
- **Cancellation Handling**: All parsers check `IsCancelled()` before processing each node and return partial results if cancelled.
|
|||
|
|
- **XML Node Validation**: All parsers skip non-`XmlElement` nodes (e.g., whitespace, comments) during iteration.
|
|||
|
|
- **Version-Specific Parsing**: Calibrations and sensors have distinct parsing logic for `importedVersion == 1.0` vs. newer versions.
|
|||
|
|
- **Group Template Validation**: `XMLParseGroupTemplates` enforces that referenced ISO test objects exist in `importObject.TestObjects()`; throws `NotSupportedException` if missing.
|
|||
|
|
- **DAS Type Validation**: `XMLParseDASList` filters out `DASHardware` with invalid `DASType` enums but does not report errors (silently drops entries).
|
|||
|
|
- **Sensor Deletion Handling**: Group and Test Setup parsers set `SensorId = 0` for deleted sensors (FB 14308) to avoid import failures.
|
|||
|
|
|
|||
|
|
## 4. Dependencies
|
|||
|
|
|
|||
|
|
### Internal Dependencies
|
|||
|
|
- **Imports**:
|
|||
|
|
- `DTS.Common.Import.Interfaces` (`ImportObject`, `IParseVariant`, `IImportNotification`, `ImportStatus`, `ImportError`, `ImportSeverityError`)
|
|||
|
|
- `DTS.Common.Interface.*` (e.g., `GroupTemplate`, `Groups.GroupList`, `Sensors`, `Channels`)
|
|||
|
|
- `DTS.SensorDB` (`SensorModel`, `SensorData`, `SensorCalibration`)
|
|||
|
|
- `DataPROWin7.DataModel` (`DASHardware`, `TestObjectTemplate`)
|
|||
|
|
- `ISO.*` (e.g., `MMEPossibleChannels`, `MMETestObjects`, `MMEPositions`, `TestEngineerDetails`, `CustomerDetails`, `LabratoryDetails`)
|
|||
|
|
- `System.Xml` (`XmlElement`, `XmlDocument`, `XmlWriter`)
|
|||
|
|
- **Shared State**:
|
|||
|
|
- Static dictionaries in `XMLParseBase` (`_dasIdMapping`, `_groupIdMapping`, `_sensorIdMapping`, `_channelIdMapping`) are shared across parsers in the same import session.
|
|||
|
|
- `ImportNotification` property used for status updates (settable via property).
|
|||
|
|
- **Constructor Injection**:
|
|||
|
|
- Pre-2.0 parsers (`XMLPre20ParseSensors`, `XMLPre20ParseDASList`, `XMLPre20ParseCalibrations`, `XMLPre20ParseGroupTemplates`) depend on their post-2.0 counterparts to perform normalization and final parsing.
|
|||
|
|
|
|||
|
|
### External Dependencies
|
|||
|
|
- `DataPROWin7.DataModel.DASHardware.ReadXML()` – Static method for pre-2.0 DAS parsing.
|
|||
|
|
- `ISO.*.ReadXML()` – Static methods for MME object parsing (e.g., `ISO.MMEPossibleChannels.ReadXML()`).
|
|||
|
|
- `User.ReadXML()` – Static method for user parsing.
|
|||
|
|
- `SensorData.ReadXML()`, `SensorCalibration.ReadXML()` – Static methods for sensor/calibration parsing.
|
|||
|
|
- `DataPROWin7.DataModel.TestObjectTemplate.ReadXML()` – Static method for group template parsing.
|
|||
|
|
|
|||
|
|
## 5. Gotchas
|
|||
|
|
|
|||
|
|
- **Silent DAS Filtering**: `XMLParseDASList.ParseDASList()` silently drops DAS entries with invalid `DASType` enums (no error logged or reported).
|
|||
|
|
- **ID Mapping Side Effects**: Static ID mappings in `XMLParseBase` are shared across parsers; clearing them (e.g., in `XMLParseDASList` constructor) may affect other parsers if not coordinated.
|
|||
|
|
- **Version-Specific Calibration Logic**: For `importedVersion == 1.0`, `XMLParseCalibrations` mutates calibration records (e.g., sets `AtCapacity = false`, infers `SensitivityUnits`). This logic is duplicated in `XMLPre20ParseCalibrations`.
|
|||
|
|
- **FB References**: Several parsers reference internal bug IDs (e.g., FB 8790, FB 14308, FB 36879) in comments or exceptions; these are internal tracking references.
|
|||
|
|
- **Test Setup Reference Resolution**: `XMLParseTestSetups.ParseTestTemplate()` uses lookup dictionaries built from `importObject` entities; if entities are not parsed in the correct order, lookups may fail (e.g., missing groups/sensors).
|
|||
|
|
- **Group Template Test Object Validation**: `XMLParseGroupTemplates` throws `NotSupportedException` if a referenced ISO test object is missing; this is a hard failure.
|
|||
|
|
- **XML Writer State**: `XMLParseBase` uses a shared `XmlWriter` instance per parser; reusing the same writer across multiple `Convert*()` calls without reinitialization may cause issues (though current code creates a new `_doc` per instance).
|
|||
|
|
- **Pre-2.0 Migration Assumptions**: `XMLPre20Parse*` parsers assume the target parser (`_xmlParse*`) handles normalization; no validation that the target parser is compatible with the migrated XML structure.
|
|||
|
|
- **Group ID Mapping Ambiguity**: `XMLParseGroups` uses `_groupIdMapping` with keys as `g.Id.ToString()` (post-2.0) or `g.Name` (pre-2.0); this dual-key approach may cause issues if group names collide with numeric IDs.
|
|||
|
|
- **Channel ID Normalization**: `XMLParseTestSetups` normalizes channel IDs *after* normalizing group IDs; order of normalization matters for cross-references.
|