Files
DP44/enriched-qwen3-coder-next/Common/DTS.Common/XMLUtils.md

140 lines
7.3 KiB
Markdown
Raw Normal View History

2026-04-17 14:55:32 -04:00
---
source_files:
- Common/DTS.Common/XMLUtils/DTSXMLFile.cs
- Common/DTS.Common/XMLUtils/NullableElement.cs
- Common/DTS.Common/XMLUtils/TestMetadataXml.cs
generated_at: "2026-04-16T02:55:32.255842+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "efe0fd52c00cf697"
---
# XMLUtils
## Documentation: `DTS.Common.XMLUtils` Module
---
### 1. Purpose
This module provides utility functions for parsing, extracting, and aggregating XML metadata from DTS test files. It supports reading attribute values from XML files (e.g., `TotalItems`), extracting inner XML content from an `XmlReader`, and consolidating multiple `.dts` XML test files into a unified `XDocument` structure for downstream processing (e.g., test execution or reporting). The module exists to abstract low-level XML handling logic and ensure consistent parsing behavior across the codebase.
---
### 2. Public Interface
#### `DTSXMLFile.GetItemsToCompleteCount(string fileName)`
```csharp
public static double GetItemsToCompleteCount(string fileName)
```
- **Behavior**: Loads the XML node from `fileName` using `FileUtils.GetImportXmlNode`, then extracts the `TotalItems` attribute value as a `double`. Returns `0.0` if the attribute is missing, invalid, or any exception occurs during parsing.
- **Note**: Uses `CultureInfo.InvariantCulture` for conversion.
#### `DTSXMLFile.GetInnerXML(XmlReader reader)`
```csharp
public static string GetInnerXML(XmlReader reader)
```
- **Behavior**: Reads the current elements inner XML text content. Assumes the reader is positioned on the start element. Advances the reader past the end element. Returns the text value of the element (or empty string if none). Throws `ArgumentException` if `reader` is `null`.
- **Implementation details**:
- Calls `reader.ReadStartElement(reader.Name)` to consume the start element.
- Reads `reader.Value` (which may be empty for non-text nodes).
- If the current node is `XmlNodeType.Text`, advances once more.
- Calls `reader.ReadEndElement()` to consume the end element.
#### `TestMetadataXml.GetTestMetadataXml(string path, string file = "", string pattern = "")`
```csharp
public static XDocument GetTestMetadataXml(string path, string file = "", string pattern = "")
```
- **Behavior**: Populates `FileUtils.FileList` with files matching `pattern` (default `".dts"`) under `path`, or adds a single `file` if provided. Then calls `SetTestMetadataType` to process the list and return a consolidated `XDocument`.
- **Output structure**:
```xml
<Tests>
<TestMetadata Id="0">
<Test DataType="ALL|ROI" FilePath="..." FileDate="..." ... />
<!-- or -->
<TestSetup ... />
</TestMetadata>
...
</Tests>
```
- **Error handling**: Logs exceptions per-file via `APILogger.Log` and continues processing remaining files. Returns an empty `XDocument` on total failure.
#### `TestMetadataXml.SetTestMetadataType(IEnumerable<string> fileList)` *(private)*
```csharp
private static XDocument SetTestMetadataType(IEnumerable<string> fileList)
```
- **Behavior**: Core logic for aggregating XML content from `fileList`. For each file:
- Reads entire file content as string.
- Splits content on `"<?xml version="` to handle multiple XML declarations in one file.
- For each XML fragment:
- Loads into `XDocument`.
- If `<Test>` element exists: adds `DataType` (`"ALL"` if filename contains `"ALL"`, else `"ROI"`), `FilePath`, and `FileDate` (creation time) as attributes.
- Adds `<Test>` or `<TestSetup>` element to a new `<TestMetadata>` container (with auto-incremented `Id` attribute).
- Aggregates all `<TestMetadata>` elements under root `<Tests>`.
---
### 3. Invariants
- **`DTSXMLFile.GetItemsToCompleteCount`**:
- Returns `0.0` for any failure (missing file, invalid XML, missing/invalid `TotalItems` attribute).
- Does not validate XML structure beyond attribute extraction.
- **`DTSXMLFile.GetInnerXML`**:
- Requires the `XmlReader` to be positioned on a start element (e.g., after `Read()` or `ReadStartElement()`).
- Always advances the reader past the end element.
- Does not handle nested elements or mixed content; only returns the *immediate* text value (`reader.Value`).
- **`TestMetadataXml.GetTestMetadataXml` / `SetTestMetadataType`**:
- `FileUtils.FileList` is mutated as a side effect (overwritten with the processed file list).
- `DataType` is determined solely by whether the filename contains `"ALL"` (case-sensitive).
- `FileDate` uses `File.GetCreationTime(file)` (system-dependent; may be unreliable on some platforms).
- XML fragments in a single file must be well-formed when prefixed with `"<?xml version="`.
---
### 4. Dependencies
#### **Internal Dependencies**
- `DTS.Common.Utils.FileUtils`:
- Used for `FileUtils.GetImportXmlNode` (in `GetItemsToCompleteCount`).
- Used for `FileUtils.FileList` (static field) and `FileUtils.FindFiles` (in `GetTestMetadataXml`).
- `DTS.Common.Utilities.Logging.APILogger`:
- Used for logging exceptions in `SetTestMetadataType`.
#### **System Dependencies**
- `System.Xml`, `System.Xml.Linq`, `System.IO`, `System.Globalization`.
#### **Depended Upon**
- Likely consumed by test orchestration, reporting, or validation modules (not evident from source).
---
### 5. Gotchas
- **`GetItemsToCompleteCount`**:
- Swallows *all* exceptions silently—no logging or differentiation between error types.
- Assumes `FileUtils.GetImportXmlNode` returns a non-null node; if it returns `null`, `node.GetAttribute(...)` will throw `NullReferenceException` (caught and returns `0.0`).
- **`GetInnerXML`**:
- Uses `reader.Value`, which may be empty for elements with child nodes (e.g., `<elem><child/></elem>``Value = ""`). Does *not* return full inner XML (despite the name).
- Assumes the element has no mixed content; text after child elements would be missed.
- **`TestMetadataXml`**:
- **Critical**: Splits XML content on `"<?xml version="`—if the XML contains this string *within* content (e.g., in a comment or attribute), it will be incorrectly split.
- `FileDate` uses `File.GetCreationTime`, which is not guaranteed to be accurate (e.g., filesystem behavior varies; may reflect copy time, not original creation).
- `Id` is a simple counter (`count++`), not derived from file content—order-dependent and non-deterministic across runs if file order changes.
- No deduplication: if a file contains multiple `<Test>` elements, they are added as separate `<Test>` children under the same `<TestMetadata>`.
- No validation of XML structure beyond checking for `<Test>` or `<TestSetup>` root elements.
- **`NullableElement<T>`**:
- `Value` throws `InvalidOperationException` if accessed when `HasValue == false`.
- `GetValueOrDefault()` returns the *default value of `T`* (e.g., `0` for `int`, `null` for reference types) if no value exists—this may be ambiguous if `T` itself is nullable.
- The `explicit operator T` may cause unexpected exceptions if used on an empty instance.
- **General**:
- No thread-safety guarantees (static fields like `FileUtils.FileList` are shared).
- `SuppressMessage` on `DTSXMLFile` indicates intentional deviation from naming conventions (acronym "DTS" preserved).
---
*Documentation generated from provided source files. No behavior inferred beyond explicit code.*