# XML Support
The `xml` subcommand splits large XML files into smaller pieces and reassembles them back into the original XML.
```bash
config-disassembler xml disassemble <path> [options]
config-disassembler xml reassemble <path> [extension] [--postpurge]
config-disassembler xml parse <path>
```
`<path>` may be a single XML file or a directory containing XML files.
---
## Basic usage
### Disassemble
```bash
config-disassembler xml disassemble flow.xml
```
Result:
```text
flow/
├── assignments/
├── decisions/
├── screens/
└── flow-meta.xml
```
### Reassemble
```bash
config-disassembler xml reassemble flow
```
### Parse
`parse` inspects how the disassembler reads an XML file without writing any output. Use it to preview the internal representation before choosing a strategy or to diagnose unexpected splits.
```bash
config-disassembler xml parse flow.xml
```
Prints the parsed structure to stdout. Useful for verifying attribute and CDATA handling before committing to a disassembly run.
---
## Disassemble options
| `--unique-id-elements <list>` | Comma-separated fields used to derive filenames | none |
| `--strategy <name>` | `unique-id` or `grouped-by-tag` | `unique-id` |
| `--format <fmt>` | Output format: `xml`, `json`, `json5`, `yaml` | `xml` |
| `--prepurge` | Remove existing output before writing | `false` |
| `--postpurge` | Delete source after success | `false` |
| `--ignore-path <path>` | Ignore file path | `.cdignore` |
| `-p`, `--split-tags <spec>` | Split/group nested tags into subdirectories | none |
| `--multi-level <spec>` | Further disassemble matching files | none |
---
## Reassemble options
| `<extension>` | Extension for rebuilt XML | `xml` |
| `--postpurge` | Delete disassembled directory after success | `false` |
---
## Disassembly strategies
### unique-id (default)
Each nested XML element is written to its own file using a unique identifier.
```bash
config-disassembler xml disassemble flow.xml \
--unique-id-elements name,id
```
Best for fine-grained diffs, version control, and large metadata files.
Example:
```text
flow/
├── decisions/
│ ├── CheckAccount.flow-meta.xml
│ └── ValidateUser.flow-meta.xml
├── screens/
└── flow-meta.xml
```
If no unique identifier is found, filenames fall back to an 8-character SHA-256 hash:
```text
419e0199.flow-meta.xml
```
#### Compound unique IDs
Combine multiple fields with `+`:
```bash
config-disassembler xml disassemble profile.xml \
--unique-id-elements \
"actionName+pageOrSobjectType+formFactor+profile"
```
Resolved values are joined with `__`:
```text
View__Account__Large__Admin.profileActionOverrides-meta.xml
```
Useful when no single field uniquely identifies sibling elements.
---
### grouped-by-tag
Groups nested elements with the same tag into shared files.
```bash
config-disassembler xml disassemble flow.xml \
--strategy grouped-by-tag
```
Best for fewer files, simpler layouts, and quick inspection.
Example:
```text
flow/
├── assignments.flow-meta.xml
├── decisions.flow-meta.xml
├── screens.flow-meta.xml
└── flow-meta.xml
```
Reassembly preserves the original structure and ordering.
---
## Split tags
With `grouped-by-tag`, specific nested tags can be split or grouped into subdirectories.
Rule format:
```text
tag:mode:field
```
Or with a path:
```text
tag:path:mode:field
```
- `mode=split` → one file per item
- `mode=group` → one file per grouped field value
Example:
```bash
config-disassembler xml disassemble permissionset.xml \
--strategy grouped-by-tag \
-p "objectPermissions:split:object,fieldPermissions:group:field"
```
Result:
```text
permissionset/
├── objectPermissions/
│ ├── Account.objectPermissions-meta.xml
│ └── Contact.objectPermissions-meta.xml
├── fieldPermissions/
└── permissionset-meta.xml
```
Reassembly automatically merges split directories back into the original XML.
---
## Output formats
XML can be split into:
- XML
- JSON
- JSON5
- YAML
```bash
config-disassembler xml disassemble flow.xml --format yaml
config-disassembler xml disassemble flow.xml --format json5
```
Regardless of split format, reassembly always produces XML.
---
## XML parser behavior
Parsing uses `quick-xml`. Supported features:
- CDATA preservation
- comment preservation
- attribute preservation
Attributes use `@` prefixes:
```xml
<root version="1.0">
```
Becomes:
```json
{ "@version": "1.0" }
```
CDATA is represented using `#cdata`.
---
## Filename safety
Resolved filenames are automatically sanitized for cross-platform compatibility:
- Path separators and reserved characters are replaced with `_`
- Invalid trailing characters are removed
- Sibling filename collisions are detected; SHA-based fallback is used when they occur
Guarantees deterministic, collision-free output across Windows, macOS, and Linux.
Example:
```text
TrustFile Transaction Sync/Import Complete
```
Becomes:
```text
TrustFile Transaction Sync_Import Complete.flow-meta.xml
```
---
## Ignore files
Directory disassembly supports `.gitignore`-style filtering via `.cdignore`:
```text
**/generated/
**/secret.xml
```
```bash
config-disassembler xml disassemble metadata/
```
For backward compatibility, `.xmldisassemblerignore` is also recognized when `.cdignore` is absent.
---
## Logging
```bash
RUST_LOG=debug config-disassembler xml disassemble flow.xml
```
---
## Multi-level disassembly
Multi-level disassembly further splits specific output files after the initial disassembly pass. Useful for deeply nested metadata structures.
Rule format:
```text
file_pattern:root_to_strip:unique_id_elements
```
Example:
```bash
config-disassembler xml disassemble \
Cloud_Kicks_Inner_Circle.loyaltyProgramSetup-meta.xml \
--unique-id-elements "fullName,name,processName" \
--multi-level \
"programProcesses:programProcesses:parameterName,ruleName"
```
This:
1. Disassembles the top-level XML
2. Matches files containing `programProcesses`
3. Unwraps the `programProcesses` root
4. Disassembles nested items again using `parameterName` and `ruleName`
A `.multi_level.json` file is written automatically so reassembly can reconstruct the original hierarchy. No additional flags are required during reassembly.
### Multiple rules
Separate rules with `;`:
```bash
config-disassembler xml disassemble Sample.multi-meta.xml \
--unique-id-elements "id,name,label" \
--multi-level \
"sectionA:sectionA:id;sectionB:sectionB:name"
```
Whitespace is trimmed. Empty trailing rules are ignored.
### Reassembly caveat
Multi-level reassembly removes intermediate directories during reconstruction, even without `--postpurge`. This is necessary so higher-level reassembly can merge rebuilt XML files correctly.
Use version control if you need to preserve intermediate disassembly trees.
---
## Examples
See [examples.md](examples.md) for complete before/after layouts and real-world metadata examples.