Task 349: .LABEL File Format

Task 349: .LABEL File Format

File Format Specifications for .LABEL

The .LABEL file format is an XML-based format developed by DYMO Corporation for their label printers (e.g., LabelWriter series). It stores label design information, including layout, text, barcodes, images, and drawing commands. The root element is typically  for die-cut labels or  for continuous tape labels. The format uses attributes like version (usually "8.0") and units (usually "twips", where 1 twip = 1/1440 inch). It includes sections for paper orientation, ID, paper name, draw commands, and object information (e.g., text, barcodes). The format is human-readable and can be edited with any XML tool, but is primarily used with DYMO software for printing.

List of all the properties of this file format intrinsic to its file system:

  • Label type (e.g., "DieCutLabel" or "ContinuousLabel")
  • Version (e.g., "8.0")
  • Units (e.g., "twips")
  • PaperOrientation (e.g., "Landscape" or "Portrait")
  • Id (unique identifier for the label type, e.g., "Address")
  • PaperName (printer driver paper name, e.g., "30252 Address")
  • DrawCommands (drawing instructions, e.g.,  with X, Y, Width, Height, Rx, Ry)
  • ObjectInfo (collection of objects on the label, including:
  • Type-specific properties, e.g., for : Name, ForeColor (Alpha, Red, Green, Blue), BackColor (Alpha, Red, Green, Blue), LinkedObjectName, Rotation (e.g., "Rotation0"), IsMirrored (True/False), IsVariable (True/False), HorizontalAlignment (e.g., "Center"), VerticalAlignment (e.g., "Middle"), TextFitMode (e.g., "ShrinkToFit"), UseFullFontHeight (True/False), Verticalized (True/False), StyledText (with  containing  and  like Font Family, Size, Bold, Italic, Underline, Strikeout, ForeColor)
  • Bounds (X, Y, Width, Height for object positioning)
    )
    Note: Other object types like , , , etc., may include similar sub-properties (e.g., BarcodeType, Image data).

Two direct download links for files of format .LABEL:

Ghost blog embedded HTML JavaScript for drag n drop .LABEL file to dump properties:

.LABEL File Dumper
Drag and drop a .LABEL file here

Python class for .LABEL file:

import xml.etree.ElementTree as ET

class LabelFile:
    def __init__(self, filepath=None):
        self.filepath = filepath
        self.tree = None
        self.root = None
        if filepath:
            self.open(filepath)

    def open(self, filepath):
        self.tree = ET.parse(filepath)
        self.root = self.tree.getroot()
        self.filepath = filepath

    def print_properties(self):
        if not self.root:
            print("No file loaded.")
            return
        print("Properties:")
        print(f"Label Type: {self.root.tag}")
        print(f"Version: {self.root.attrib.get('Version')}")
        print(f"Units: {self.root.attrib.get('Units')}")
        print(f"PaperOrientation: {self.root.findtext('PaperOrientation')}")
        print(f"Id: {self.root.findtext('Id')}")
        print(f"PaperName: {self.root.findtext('PaperName')}")
        draw_commands = self.root.find('DrawCommands')
        if draw_commands is not None:
            print("DrawCommands:")
            for cmd in draw_commands:
              print(f"  - {cmd.tag}: {', '.join([f'{k}={v}' for k,v in cmd.attrib.items()])}")
        object_infos = self.root.findall('ObjectInfo')
        for idx, obj in enumerate(object_infos, 1):
            print(f"ObjectInfo {idx}:")
            text_obj = obj.find('TextObject')
            if text_obj is not None:
              print("  Type: TextObject")
              print(f"  Name: {text_obj.findtext('Name')}")
              fore_color = text_obj.find('ForeColor')
              if fore_color is not None:
                  print(f"  ForeColor: Alpha={fore_color.attrib.get('Alpha')}, Red={fore_color.attrib.get('Red')}, Green={fore_color.attrib.get('Green')}, Blue={fore_color.attrib.get('Blue')}")
              back_color = text_obj.find('BackColor')
              if back_color is not None:
                  print(f"  BackColor: Alpha={back_color.attrib.get('Alpha')}, Red={back_color.attrib.get('Red')}, Green={back_color.attrib.get('Green')}, Blue={back_color.attrib.get('Blue')}")
              print(f"  LinkedObjectName: {text_obj.findtext('LinkedObjectName')}")
              print(f"  Rotation: {text_obj.findtext('Rotation')}")
              print(f"  IsMirrored: {text_obj.findtext('IsMirrored')}")
              print(f"  IsVariable: {text_obj.findtext('IsVariable')}")
              print(f"  HorizontalAlignment: {text_obj.findtext('HorizontalAlignment')}")
              print(f"  VerticalAlignment: {text_obj.findtext('VerticalAlignment')}")
              print(f"  TextFitMode: {text_obj.findtext('TextFitMode')}")
              print(f"  UseFullFontHeight: {text_obj.findtext('UseFullFontHeight')}")
              print(f"  Verticalized: {text_obj.findtext('Verticalized')}")
              styled_text = text_obj.find('StyledText')
              if styled_text is not None:
                  print("  StyledText:")
                  for el in styled_text.findall('Element'):
                      print(f"    String: {el.findtext('String')}")
                      attrs = el.find('Attributes')
                      font = attrs.find('Font')
                      if font is not None:
                          print(f"    Font: Family={font.attrib.get('Family')}, Size={font.attrib.get('Size')}, Bold={font.attrib.get('Bold')}, Italic={font.attrib.get('Italic')}, Underline={font.attrib.get('Underline')}, Strikeout={font.attrib.get('Strikeout')}")
                      color = attrs.find('ForeColor')
                      if color is not None:
                          print(f"    ForeColor: Alpha={color.attrib.get('Alpha')}, Red={color.attrib.get('Red')}, Green={color.attrib.get('Green')}, Blue={color.attrib.get('Blue')}") 
            # Add for other object types if needed
            bounds = obj.find('Bounds')
            if bounds is not None:
                print(f"  Bounds: X={bounds.attrib.get('X')}, Y={bounds.attrib.get('Y')}, Width={bounds.attrib.get('Width')}, Height={bounds.attrib.get('Height')}")

    def write(self, new_filepath=None):
        if not self.tree:
            # Create a default new label if no tree loaded
            self.root = ET.Element('DieCutLabel', {'Version': '8.0', 'Units': 'twips'})
            ET.SubElement(self.root, 'PaperOrientation').text = 'Landscape'
            ET.SubElement(self.root, 'Id').text = 'Address'
            ET.SubElement(self.root, 'PaperName').text = '30252 Address'
            draw_commands = ET.SubElement(self.root, 'DrawCommands')
            ET.SubElement(draw_commands, 'RoundRectangle', {'X': '0', 'Y': '0', 'Width': '1581', 'Height': '5040', 'Rx': '270', 'Ry': '270'})
            self.tree = ET.ElementTree(self.root)
        filepath = new_filepath or self.filepath
        self.tree.write(filepath, encoding='utf-8', xml_declaration=True)

# Example usage:
# lf = LabelFile('example.label')
# lf.print_properties()
# lf.write('new.label')

Java class for .LABEL file:

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;

public class LabelFile {
    private String filepath;
    private Document doc;

    public LabelFile(String filepath) {
        this.filepath = filepath;
        open(filepath);
    }

    public void open(String filepath) {
        try {
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            doc = dBuilder.parse(filepath);
            doc.getDocumentElement().normalize();
            this.filepath = filepath;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void printProperties() {
        if (doc == null) {
            System.out.println("No file loaded.");
            return;
        }
        Element root = doc.getDocumentElement();
        System.out.println("Properties:");
        System.out.println("Label Type: " + root.getTagName());
        System.out.println("Version: " + root.getAttribute("Version"));
        System.out.println("Units: " + root.getAttribute("Units"));
        System.out.println("PaperOrientation: " + getTextContent(root, "PaperOrientation"));
        System.out.println("Id: " + getTextContent(root, "Id"));
        System.out.println("PaperName: " + getTextContent(root, "PaperName"));
        Element drawCommands = (Element) root.getElementsByTagName("DrawCommands").item(0);
        if (drawCommands != null) {
            System.out.println("DrawCommands:");
            NodeList commands = drawCommands.getChildNodes();
            for (int i = 0; i < commands.getLength(); i++) {
                if (commands.item(i) instanceof Element) {
                    Element cmd = (Element) commands.item(i);
                    System.out.print("  - " + cmd.getTagName() + ": ");
                    for (int j = 0; j < cmd.getAttributes().getLength(); j++) {
                        Node attr = cmd.getAttributes().item(j);
                        System.out.print(attr.getNodeName() + "=" + attr.getNodeValue() + ", ");
                    }
                    System.out.println();
                }
            }
        }
        NodeList objectInfos = root.getElementsByTagName("ObjectInfo");
        for (int idx = 0; idx < objectInfos.getLength(); idx++) {
            Element obj = (Element) objectInfos.item(idx);
            System.out.println("ObjectInfo " + (idx + 1) + ":");
            Element textObj = (Element) obj.getElementsByTagName("TextObject").item(0);
            if (textObj != null) {
                System.out.println("  Type: TextObject");
                System.out.println("  Name: " + getTextContent(textObj, "Name"));
                Element foreColor = (Element) textObj.getElementsByTagName("ForeColor").item(0);
                if (foreColor != null) {
                    System.out.println("  ForeColor: Alpha=" + foreColor.getAttribute("Alpha") + ", Red=" + foreColor.getAttribute("Red") + ", Green=" + foreColor.getAttribute("Green") + ", Blue=" + foreColor.getAttribute("Blue"));
                }
                Element backColor = (Element) textObj.getElementsByTagName("BackColor").item(0);
                if (backColor != null) {
                    System.out.println("  BackColor: Alpha=" + backColor.getAttribute("Alpha") + ", Red=" + backColor.getAttribute("Red") + ", Green=" + backColor.getAttribute("Green") + ", Blue=" + backColor.getAttribute("Blue"));
                }
                System.out.println("  LinkedObjectName: " + getTextContent(textObj, "LinkedObjectName"));
                System.out.println("  Rotation: " + getTextContent(textObj, "Rotation"));
                System.out.println("  IsMirrored: " + getTextContent(textObj, "IsMirrored"));
                System.out.println("  IsVariable: " + getTextContent(textObj, "IsVariable"));
                System.out.println("  HorizontalAlignment: " + getTextContent(textObj, "HorizontalAlignment"));
                System.out.println("  VerticalAlignment: " + getTextContent(textObj, "VerticalAlignment"));
                System.out.println("  TextFitMode: " + getTextContent(textObj, "TextFitMode"));
                System.out.println("  UseFullFontHeight: " + getTextContent(textObj, "UseFullFontHeight"));
                System.out.println("  Verticalized: " + getTextContent(textObj, "Verticalized"));
                Element styledText = (Element) textObj.getElementsByTagName("StyledText").item(0);
                if (styledText != null) {
                    System.out.println("  StyledText:");
                    NodeList elements = styledText.getElementsByTagName("Element");
                    for (int k = 0; k < elements.getLength(); k++) {
                        Element el = (Element) elements.item(k);
                        System.out.println("    String: " + getTextContent(el, "String"));
                        Element attrs = (Element) el.getElementsByTagName("Attributes").item(0);
                        Element font = (Element) attrs.getElementsByTagName("Font").item(0);
                        if (font != null) {
                            System.out.println("    Font: Family=" + font.getAttribute("Family") + ", Size=" + font.getAttribute("Size") + ", Bold=" + font.getAttribute("Bold") + ", Italic=" + font.getAttribute("Italic") + ", Underline=" + font.getAttribute("Underline") + ", Strikeout=" + font.getAttribute("Strikeout"));
                        }
                        Element color = (Element) attrs.getElementsByTagName("ForeColor").item(0);
                        if (color != null) {
                            System.out.println("    ForeColor: Alpha=" + color.getAttribute("Alpha") + ", Red=" + color.getAttribute("Red") + ", Green=" + color.getAttribute("Green") + ", Blue=" + color.getAttribute("Blue"));
                        }
                    }
                }
            }
            // Add for other object types if needed
            Element bounds = (Element) obj.getElementsByTagName("Bounds").item(0);
            if (bounds != null) {
                System.out.println("  Bounds: X=" + bounds.getAttribute("X") + ", Y=" + bounds.getAttribute("Y") + ", Width=" + bounds.getAttribute("Width") + ", Height=" + bounds.getAttribute("Height"));
            }
        }
    }

    private String getTextContent(Element parent, String tag) {
        Node node = parent.getElementsByTagName(tag).item(0);
        return node != null ? node.getTextContent() : null;
    }

    public void write(String newFilepath) {
        try {
            if (doc == null) {
                DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
                DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
                doc = dBuilder.newDocument();
                Element root = doc.createElement("DieCutLabel");
                root.setAttribute("Version", "8.0");
                root.setAttribute("Units", "twips");
                doc.appendChild(root);
                Element orientation = doc.createElement("PaperOrientation");
                orientation.setTextContent("Landscape");
                root.appendChild(orientation);
                Element id = doc.createElement("Id");
                id.setTextContent("Address");
                root.appendChild(id);
                Element paperName = doc.createElement("PaperName");
                paperName.setTextContent("30252 Address");
                root.appendChild(paperName);
                Element drawCommands = doc.createElement("DrawCommands");
                root.appendChild(drawCommands);
                Element roundRect = doc.createElement("RoundRectangle");
                roundRect.setAttribute("X", "0");
                roundRect.setAttribute("Y", "0");
                roundRect.setAttribute("Width", "1581");
                roundRect.setAttribute("Height", "5040");
                roundRect.setAttribute("Rx", "270");
                roundRect.setAttribute("Ry", "270");
                drawCommands.appendChild(roundRect);
            }
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            DOMSource source = new DOMSource(doc);
            StreamResult result = new StreamResult(newFilepath != null ? newFilepath : filepath);
            transformer.transform(source, result);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // Example usage:
    // public static void main(String[] args) {
    //     LabelFile lf = new LabelFile("example.label");
    //     lf.printProperties();
    //     lf.write("new.label");
    // }
}

JavaScript class for .LABEL file (Node.js, requires 'fs' and 'xml2js' for parsing; install xml2js if needed):

const fs = require('fs');
const xml2js = require('xml2js');

class LabelFile {
    constructor(filepath = null) {
        this.filepath = filepath;
        this.data = null;
        if (filepath) {
            this.open(filepath);
        }
    }

    open(filepath) {
        const xml = fs.readFileSync(filepath, 'utf8');
        const parser = new xml2js.Parser();
        parser.parseString(xml, (err, result) => {
            if (err) {
                console.error('Error parsing XML:', err);
            } else {
                this.data = result;
            }
        });
        this.filepath = filepath;
    }

    printProperties() {
        if (!this.data) {
            console.log('No file loaded.');
            return;
        }
        const root = this.data.DieCutLabel || this.data.ContinuousLabel;
        console.log('Properties:');
        console.log(`Label Type: ${Object.keys(this.data)[0]}`);
        console.log(`Version: ${root.$?.Version}`);
        console.log(`Units: ${root.$?.Units}`);
        console.log(`PaperOrientation: ${root.PaperOrientation?.[0]}`);
        console.log(`Id: ${root.Id?.[0]}`);
        console.log(`PaperName: ${root.PaperName?.[0]}`);
        const drawCommands = root.DrawCommands?.[0];
        if (drawCommands) {
            console.log('DrawCommands:');
            Object.keys(drawCommands).forEach(key => {
                const cmd = drawCommands[key][0].$;
                console.log(`  - ${key}: ${Object.entries(cmd).map(([k, v]) => `${k}=${v}`).join(', ')}`);
            });
        }
        const objectInfos = root.ObjectInfo;
        if (objectInfos) {
            objectInfos.forEach((obj, idx) => {
                console.log(`ObjectInfo ${idx + 1}:`);
                const textObj = obj.TextObject?.[0];
                if (textObj) {
                    console.log('  Type: TextObject');
                    console.log(`  Name: ${textObj.Name?.[0]}`);
                    const foreColor = textObj.ForeColor?.[0].$;
                    console.log(`  ForeColor: Alpha=${foreColor.Alpha}, Red=${foreColor.Red}, Green=${foreColor.Green}, Blue=${foreColor.Blue}`);
                    const backColor = textObj.BackColor?.[0].$;
                    console.log(`  BackColor: Alpha=${backColor.Alpha}, Red=${backColor.Red}, Green=${backColor.Green}, Blue=${backColor.Blue}`);
                    console.log(`  LinkedObjectName: ${textObj.LinkedObjectName?.[0]}`);
                    console.log(`  Rotation: ${textObj.Rotation?.[0]}`);
                    console.log(`  IsMirrored: ${textObj.IsMirrored?.[0]}`);
                    console.log(`  IsVariable: ${textObj.IsVariable?.[0]}`);
                    console.log(`  HorizontalAlignment: ${textObj.HorizontalAlignment?.[0]}`);
                    console.log(`  VerticalAlignment: ${textObj.VerticalAlignment?.[0]}`);
                    console.log(`  TextFitMode: ${textObj.TextFitMode?.[0]}`);
                    console.log(`  UseFullFontHeight: ${textObj.UseFullFontHeight?.[0]}`);
                    console.log(`  Verticalized: ${textObj.Verticalized?.[0]}`);
                    const styledText = textObj.StyledText?.[0];
                    if (styledText) {
                        console.log('  StyledText:');
                        styledText.Element.forEach(el => {
                            console.log(`    String: ${el.String?.[0]}`);
                            const attrs = el.Attributes?.[0];
                            const font = attrs.Font?.[0].$;
                            console.log(`    Font: Family=${font.Family}, Size=${font.Size}, Bold=${font.Bold}, Italic=${font.Italic}, Underline=${font.Underline}, Strikeout=${font.Strikeout}`);
                            const color = attrs.ForeColor?.[0].$;
                            console.log(`    ForeColor: Alpha=${color.Alpha}, Red=${color.Red}, Green=${color.Green}, Blue=${color.Blue}`);
                        });
                    }
                }
                // Add for other object types if needed
                const bounds = obj.Bounds?.[0].$;
                console.log(`  Bounds: X=${bounds.X}, Y=${bounds.Y}, Width=${bounds.Width}, Height=${bounds.Height}`);
            });
        }
    }

    write(newFilepath = null) {
        const filepath = newFilepath || this.filepath;
        if (!this.data) {
            // Create default
            this.data = {
                DieCutLabel: {
                    $: { Version: '8.0', Units: 'twips' },
                    PaperOrientation: ['Landscape'],
                    Id: ['Address'],
                    PaperName: ['30252 Address'],
                    DrawCommands: [{
                        RoundRectangle: [{ $: { X: '0', Y: '0', Width: '1581', Height: '5040', Rx: '270', Ry: '270' } }]
                    }]
                }
            };
        }
        const builder = new xml2js.Builder({ renderOpts: { pretty: true, indent: '  ', newline: '\n' }, xmldec: { version: '1.0', encoding: 'utf-8' } });
        const xml = builder.buildObject(this.data);
        fs.writeFileSync(filepath, xml);
    }
}

// Example usage:
// const lf = new LabelFile('example.label');
// lf.printProperties();
// lf.write('new.label');

C class (using C++ for class support, with tinyxml2 for XML parsing; assume tinyxml2 is included):

#include <iostream>
#include <fstream>
#include "tinyxml2.h" // Assume tinyxml2 library is linked

using namespace tinyxml2;

class LabelFile {
private:
    std::string filepath;
    XMLDocument doc;

public:
    LabelFile(const std::string& fp = "") : filepath(fp) {
        if (!fp.empty()) {
            open(fp);
        }
    }

    void open(const std::string& fp) {
        if (doc.LoadFile(fp.c_str()) != XML_SUCCESS) {
            std::cerr << "Error loading file." << std::endl;
        }
        filepath = fp;
    }

    void printProperties() {
        XMLElement* root = doc.FirstChildElement();
        if (!root) {
            std::cout << "No file loaded." << std::endl;
            return;
        }
        std::cout << "Properties:" << std::endl;
        std::cout << "Label Type: " << root->Name() << std::endl;
        std::cout << "Version: " << (root->Attribute("Version") ? root->Attribute("Version") : "N/A") << std::endl;
        std::cout << "Units: " << (root->Attribute("Units") ? root->Attribute("Units") : "N/A") << std::endl;
        std::cout << "PaperOrientation: " << (root->FirstChildElement("PaperOrientation") ? root->FirstChildElement("PaperOrientation")->GetText() : "N/A") << std::endl;
        std::cout << "Id: " << (root->FirstChildElement("Id") ? root->FirstChildElement("Id")->GetText() : "N/A") << std::endl;
        std::cout << "PaperName: " << (root->FirstChildElement("PaperName") ? root->FirstChildElement("PaperName")->GetText() : "N/A") << std::endl;
        XMLElement* drawCommands = root->FirstChildElement("DrawCommands");
        if (drawCommands) {
            std::cout << "DrawCommands:" << std::endl;
            for (XMLElement* cmd = drawCommands->FirstChildElement(); cmd; cmd = cmd->NextSiblingElement()) {
                std::cout << "  - " << cmd->Name() << ": ";
                for (const XMLAttribute* attr = cmd->FirstAttribute(); attr; attr = attr->Next()) {
                    std::cout << attr->Name() << "=" << attr->Value() << ", ";
                }
                std::cout << std::endl;
            }
        }
        int idx = 1;
        for (XMLElement* obj = root->FirstChildElement("ObjectInfo"); obj; obj = obj->NextSiblingElement("ObjectInfo"), ++idx) {
            std::cout << "ObjectInfo " << idx << ":" << std::endl;
            XMLElement* textObj = obj->FirstChildElement("TextObject");
            if (textObj) {
                std::cout << "  Type: TextObject" << std::endl;
                std::cout << "  Name: " << (textObj->FirstChildElement("Name") ? textObj->FirstChildElement("Name")->GetText() : "N/A") << std::endl;
                XMLElement* foreColor = textObj->FirstChildElement("ForeColor");
                if (foreColor) {
                    std::cout << "  ForeColor: Alpha=" << foreColor->Attribute("Alpha") << ", Red=" << foreColor->Attribute("Red") << ", Green=" << foreColor->Attribute("Green") << ", Blue=" << foreColor->Attribute("Blue") << std::endl;
                }
                XMLElement* backColor = textObj->FirstChildElement("BackColor");
                if (backColor) {
                    std::cout << "  BackColor: Alpha=" << backColor->Attribute("Alpha") << ", Red=" << backColor->Attribute("Red") << ", Green=" << backColor->Attribute("Green") << ", Blue=" << backColor->Attribute("Blue") << std::endl;
                }
                std::cout << "  LinkedObjectName: " << (textObj->FirstChildElement("LinkedObjectName") ? textObj->FirstChildElement("LinkedObjectName")->GetText() : "N/A") << std::endl;
                std::cout << "  Rotation: " << (textObj->FirstChildElement("Rotation") ? textObj->FirstChildElement("Rotation")->GetText() : "N/A") << std::endl;
                std::cout << "  IsMirrored: " << (textObj->FirstChildElement("IsMirrored") ? textObj->FirstChildElement("IsMirrored")->GetText() : "N/A") << std::endl;
                std::cout << "  IsVariable: " << (textObj->FirstChildElement("IsVariable") ? textObj->FirstChildElement("IsVariable")->GetText() : "N/A") << std::endl;
                std::cout << "  HorizontalAlignment: " << (textObj->FirstChildElement("HorizontalAlignment") ? textObj->FirstChildElement("HorizontalAlignment")->GetText() : "N/A") << std::endl;
                std::cout << "  VerticalAlignment: " << (textObj->FirstChildElement("VerticalAlignment") ? textObj->FirstChildElement("VerticalAlignment")->GetText() : "N/A") << std::endl;
                std::cout << "  TextFitMode: " << (textObj->FirstChildElement("TextFitMode") ? textObj->FirstChildElement("TextFitMode")->GetText() : "N/A") << std::endl;
                std::cout << "  UseFullFontHeight: " << (textObj->FirstChildElement("UseFullFontHeight") ? textObj->FirstChildElement("UseFullFontHeight")->GetText() : "N/A") << std::endl;
                std::cout << "  Verticalized: " << (textObj->FirstChildElement("Verticalized") ? textObj->FirstChildElement("Verticalized")->GetText() : "N/A") << std::endl;
                XMLElement* styledText = textObj->FirstChildElement("StyledText");
                if (styledText) {
                    std::cout << "  StyledText:" << std::endl;
                    for (XMLElement* el = styledText->FirstChildElement("Element"); el; el = el->NextSiblingElement("Element")) {
                        std::cout << "    String: " << (el->FirstChildElement("String") ? el->FirstChildElement("String")->GetText() : "N/A") << std::endl;
                        XMLElement* attrs = el->FirstChildElement("Attributes");
                        XMLElement* font = attrs->FirstChildElement("Font");
                        if (font) {
                            std::cout << "    Font: Family=" << font->Attribute("Family") << ", Size=" << font->Attribute("Size") << ", Bold=" << font->Attribute("Bold") << ", Italic=" << font->Attribute("Italic") << ", Underline=" << font->Attribute("Underline") << ", Strikeout=" << font->Attribute("Strikeout") << std::endl;
                        }
                        XMLElement* color = attrs->FirstChildElement("ForeColor");
                        if (color) {
                            std::cout << "    ForeColor: Alpha=" << color->Attribute("Alpha") << ", Red=" << color->Attribute("Red") << ", Green=" << color->Attribute("Green") << ", Blue=" << color->Attribute("Blue") << std::endl;
                        }
                    }
                }
            }
            // Add for other object types if needed
            XMLElement* bounds = obj->FirstChildElement("Bounds");
            if (bounds) {
                std::cout << "  Bounds: X=" << bounds->Attribute("X") << ", Y=" << bounds->Attribute("Y") << ", Width=" << bounds->Attribute("Width") << ", Height=" << bounds->Attribute("Height") << std::endl;
            }
        }
    }

    void write(const std::string& newFilepath = "") {
        const std::string fp = newFilepath.empty() ? filepath : newFilepath;
        if (doc.NoChildren()) {
            XMLElement* root = doc.NewElement("DieCutLabel");
            root->SetAttribute("Version", "8.0");
            root->SetAttribute("Units", "twips");
            doc.InsertFirstChild(root);
            XMLElement* orientation = doc.NewElement("PaperOrientation");
            orientation->SetText("Landscape");
            root->InsertEndChild(orientation);
            XMLElement* id = doc.NewElement("Id");
            id->SetText("Address");
            root->InsertEndChild(id);
            XMLElement* paperName = doc.NewElement("PaperName");
            paperName->SetText("30252 Address");
            root->InsertEndChild(paperName);
            XMLElement* drawCommands = doc.NewElement("DrawCommands");
            root->InsertEndChild(drawCommands);
            XMLElement* roundRect = doc.NewElement("RoundRectangle");
            roundRect->SetAttribute("X", "0");
            roundRect->SetAttribute("Y", "0");
            roundRect->SetAttribute("Width", "1581");
            roundRect->SetAttribute("Height", "5040");
            roundRect->SetAttribute("Rx", "270");
            roundRect->SetAttribute("Ry", "270");
            drawCommands->InsertEndChild(roundRect);
        }
        doc.SaveFile(fp.c_str());
    }
};

// Example usage:
// int main() {
//     LabelFile lf("example.label");
//     lf.printProperties();
//     lf.write("new.label");
//     return 0;
// }