PLCProject XML Schema Reference - Version 2.0¶
Document Version: 1.0 Schema Version: 2.0 Last Updated: 2026-01-25 Status: Active
Overview¶
The PLCProject XML format is the native file format for PiPLC ladder logic projects. Files use the .plcproj extension and contain complete project data including metadata, symbol tables, and ladder logic programs.
File Format Basics¶
- Encoding: UTF-8 (with XML declaration)
- Extension:
.plcproj - MIME Type:
application/x-plcproject+xml - XML Version: 1.0
Schema Version History¶
| Version | Date | Changes |
|---|---|---|
| 2.0 | 2026-01-25 | Initial documented schema with streaming XML support |
| 1.0 | (Legacy) | Reserved for future backwards compatibility |
Root Element¶
<?xml version="1.0" encoding="UTF-8"?>
<PLCProject version="2.0">
<!-- Child elements -->
</PLCProject>
Attributes¶
| Attribute | Type | Required | Description |
|---|---|---|---|
version | string | Yes | Schema version (e.g., "2.0"). Required for compatibility checking. |
Child Elements (in order)¶
Metadata- Project metadata (required)SymbolTable- Variable definitions (required, may be empty)Programs- Ladder logic programs (required)
Metadata Element¶
Contains project identification and descriptive information.
<Metadata>
<Name>Motor Control</Name>
<Description>Optional description of the project</Description>
</Metadata>
Child Elements¶
| Element | Type | Required | Description |
|---|---|---|---|
Name | string | No | Project name. Empty string if not specified. |
Description | string | No | Project description. Omitted if empty. |
Notes¶
- Special XML characters (
<,>,&,",') are automatically escaped - Unicode content is fully supported
SymbolTable Element¶
Contains variable/symbol definitions used in the ladder logic.
<SymbolTable>
<Symbol name="StartButton" type="BOOL" address="I:0/0" description="Main start pushbutton" />
<Symbol name="MotorRunning" type="BOOL" address="O:0/0" />
<Symbol name="CycleCount" type="INT" address="N:10" description="Production counter" />
</SymbolTable>
Symbol Element Attributes¶
| Attribute | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Unique variable name. Must follow naming rules (alphanumeric + underscore, no leading digits). |
address | string | Yes | PLC memory address. See Address Formats below. |
type | string | No | Data type: BOOL, INT, DINT, REAL, TIMER, COUNTER. Defaults to BOOL. |
description | string | No | Human-readable description. Omitted if empty. |
Validation Rules¶
- Variable names must be unique within the symbol table
- Duplicate names will cause a load error
- Address must be valid per the Address Formats specification
Programs Element¶
Contains one or more ladder logic programs.
<Programs>
<Program name="MainProgram" type="Main">
<Rungs>
<!-- Rung elements -->
</Rungs>
</Program>
</Programs>
Program Element Attributes¶
| Attribute | Type | Required | Description |
|---|---|---|---|
name | string | No | Program name (informational, may differ from Metadata name) |
type | string | No | Program type: Main, Subroutine, Interrupt. Default: Main |
Notes¶
- Currently only single-program projects are supported
- The authoritative program name comes from
Metadata/Name, not the Program element'snameattribute
Rungs Element¶
Contains the ladder rungs within a program.
<Rungs>
<Rung id="0" comment="Start/stop circuit with seal-in">
<!-- Instruction elements -->
</Rung>
<Rung id="1">
<!-- Instruction elements -->
</Rung>
</Rungs>
Rung Element Attributes¶
| Attribute | Type | Required | Description |
|---|---|---|---|
id | integer | No | Rung identifier (0-based). Used for reference only. |
comment | string | No | Rung comment/description. Omitted if empty. |
Instruction Element¶
Represents a single ladder logic instruction.
<Instruction type="XIC" address="I:0/0" column="0" />
<Instruction type="OTE" address="O:0/0" column="10" />
Attributes¶
| Attribute | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Instruction type. See Instruction Types below. |
address | string | Yes | Target memory address. See Address Formats below. |
column | integer | No | Visual column position in ladder editor. Default: 0 |
Instruction Types¶
Contact Instructions (Input)¶
| Type | Name | Description |
|---|---|---|
XIC | Examine If Closed | TRUE when addressed bit is 1 |
XIO | Examine If Open | TRUE when addressed bit is 0 |
Coil Instructions (Output)¶
| Type | Name | Description |
|---|---|---|
OTE | Output Energize | Sets bit to match rung continuity |
OTL | Output Latch | Sets bit TRUE on rung TRUE, retains on FALSE |
OTU | Output Unlatch | Sets bit FALSE on rung TRUE, retains on FALSE |
Future Instruction Types (Planned for M4)¶
TON,TOF,RTO- Timer instructionsCTU,CTD- Counter instructionsADD,SUB,MUL,DIV- Math instructionsEQU,NEQ,GRT,LES,GEQ,LEQ- Comparison instructionsJMP,JSR,RET- Program control instructions
Address Formats¶
PiPLC uses Allen-Bradley/Rockwell-style PLC addressing.
Bit Addresses¶
Format: R:W/B where: - R = Region prefix - W = Word number (0-based) - B = Bit number (0-15)
| Region | Prefix | Description | Example |
|---|---|---|---|
| Input | I | Digital inputs | I:0/0, I:1/15 |
| Output | O | Digital outputs | O:0/0, O:0/7 |
| Bit | B | Internal relays | B:3/0, B:10/8 |
Word Addresses¶
Format: R:W where: - R = Region prefix - W = Word/element number
| Region | Prefix | Description | Example |
|---|---|---|---|
| Integer | N | 16-bit signed integers | N:0, N:100 |
| Timer | T | Timer structures | T:0, T:10 |
| Counter | C | Counter structures | C:0, C:5 |
Timer/Counter Sub-Elements¶
Format: R:W.S where S is:
| Sub-element | Description | Type |
|---|---|---|
.DN | Done bit | BOOL |
.TT | Timer timing / Counter counting | BOOL |
.EN | Enabled | BOOL |
.ACC | Accumulated value | INT |
.PRE | Preset value | INT |
Examples: T:0.DN, C:5.ACC, T:2.PRE
Complete Example¶
<?xml version="1.0" encoding="UTF-8"?>
<PLCProject version="2.0">
<Metadata>
<Name>Motor Control Example</Name>
<Description>Simple motor start/stop circuit with seal-in relay</Description>
</Metadata>
<SymbolTable>
<Symbol name="StartPB" type="BOOL" address="I:0/0" description="Start pushbutton (NO)" />
<Symbol name="StopPB" type="BOOL" address="I:0/1" description="Stop pushbutton (NC)" />
<Symbol name="Overload" type="BOOL" address="I:0/2" description="Motor overload contact (NC)" />
<Symbol name="MotorOut" type="BOOL" address="O:0/0" description="Motor contactor output" />
<Symbol name="SealIn" type="BOOL" address="B:0/0" description="Motor seal-in relay" />
<Symbol name="RunIndicator" type="BOOL" address="O:0/1" description="Motor running pilot light" />
</SymbolTable>
<Programs>
<Program name="Motor Control Example" type="Main">
<Rungs>
<Rung id="0" comment="Motor start circuit - Start OR Seal-in, AND NOT Stop, AND NOT Overload">
<Instruction type="XIC" address="I:0/0" column="0" />
<Instruction type="XIC" address="B:0/0" column="1" />
<Instruction type="XIO" address="I:0/1" column="2" />
<Instruction type="XIO" address="I:0/2" column="3" />
<Instruction type="OTE" address="B:0/0" column="10" />
</Rung>
<Rung id="1" comment="Motor output from seal-in">
<Instruction type="XIC" address="B:0/0" column="0" />
<Instruction type="OTE" address="O:0/0" column="10" />
</Rung>
<Rung id="2" comment="Running indicator">
<Instruction type="XIC" address="B:0/0" column="0" />
<Instruction type="OTE" address="O:0/1" column="10" />
</Rung>
</Rungs>
</Program>
</Programs>
</PLCProject>
Error Handling¶
Load Errors¶
The loader reports errors with line and column numbers when possible:
| Error | Description |
|---|---|
No PLCProject element found | Root element missing or malformed XML |
Missing version attribute | Required version attribute not present |
Symbol missing name attribute | Symbol element lacks required name |
Symbol missing address attribute | Symbol element lacks required address |
Invalid address: X:Y/Z | Address format not recognized |
Duplicate variable name: Name | Symbol table contains duplicate names |
Unknown instruction type: TYPE | Instruction type not recognized |
Instruction missing type attribute | Instruction element lacks required type |
Forward Compatibility¶
- Unknown elements are silently skipped
- Unknown attributes are ignored
- This allows newer schema versions to be partially read by older software
Implementation Notes¶
Writing Projects¶
Use QXmlStreamWriter for generating XML: - Auto-formatting enabled with 2-space indentation - UTF-8 encoding with XML declaration - Empty elements written as <Element /> (self-closing)
Reading Projects¶
Use QXmlStreamReader for parsing: - Streaming parser for memory efficiency - Element-by-element processing - Error recovery via skipCurrentElement()
API Reference¶
// Save to file
bool ProjectSerializer::save(const Program *program, const QString &filePath, QString *error);
// Save to device (for testing)
bool ProjectSerializer::save(const Program *program, QIODevice *device, QString *error);
// Load from file
Program* ProjectSerializer::load(const QString &filePath, QString *error);
// Load from device (for testing)
Program* ProjectSerializer::load(QIODevice *device, QString *error);
See Also¶
- SPECIFICATION.md Section 3 - File format requirements
- ProjectSerializer.h - Implementation header
- examples/ - Example project files