{"id":8018,"library":"cmeel-tinyxml2","title":"cmeel-tinyxml2: Python Bindings for TinyXML-2","description":"cmeel-tinyxml2 provides efficient Python bindings for TinyXML-2, a small, fast, and simple C++ XML parser. It allows Python developers to leverage the underlying C++ library's performance for parsing, creating, and manipulating XML documents directly from Python. The current version is 10.0.0, with releases typically aligning with upstream TinyXML-2 updates and the `cmeel` packaging cycle.","status":"active","version":"10.0.0","language":"en","source_language":"en","source_url":"https://github.com/cmake-wheel/cmeel-tinyxml2.git","tags":["xml","tinyxml2","c++","bindings","cmeel","parsing","serialization"],"install":[{"cmd":"pip install cmeel-tinyxml2","lang":"bash","label":"Install stable version"}],"dependencies":[],"imports":[{"symbol":"tinyxml2","correct":"import tinyxml2"},{"symbol":"XMLDocument","correct":"import tinyxml2\ndoc = tinyxml2.XMLDocument()"},{"symbol":"XMLElement","correct":"import tinyxml2\nelem = tinyxml2.XMLElement('tag')"}],"quickstart":{"code":"import tinyxml2\nimport os\n\n# Create a new document\ndoc = tinyxml2.XMLDocument()\n\n# Add a declaration (optional but good practice)\ndoc.InsertEndChild(doc.NewDeclaration(\"xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"\"))\n\n# Create a root element\nroot = doc.NewElement(\"Root\")\ndoc.InsertEndChild(root)\n\n# Add a child element with an attribute and text\nchild = doc.NewElement(\"Item\")\nchild.SetAttribute(\"id\", 123)\nchild.SetText(\"Example Text\")\nroot.InsertEndChild(child)\n\n# Add another child\nanother_child = doc.NewElement(\"SubItem\")\nanother_child.SetText(\"More data\")\nchild.InsertEndChild(another_child)\n\n# Print the document to stdout\nprinter = tinyxml2.XMLPrinter()\ndoc.Print(printer)\nprint(\"\\n--- Generated XML ---\")\nprint(printer.CStr())\n\n# Example of parsing an XML string\nxml_string = \"<data><item value='parsed_value'/></data>\"\nparsed_doc = tinyxml2.XMLDocument()\nparsed_doc.Parse(xml_string)\n\nprint(\"\\n--- Parsed XML Content ---\")\nif not parsed_doc.Error():\n    root_element = parsed_doc.FirstChildElement(\"data\")\n    if root_element:\n        item_element = root_element.FirstChildElement(\"item\")\n        if item_element:\n            print(f\"Parsed item value: {item_element.Attribute('value')}\")\n        else:\n            print(\"Item element not found.\")\n    else:\n        print(\"Data root element not found.\")\nelif parsed_doc.ErrorID() == tinyxml2.XML_NO_ERROR:\n    print(\"Parsing completed with no document errors, but might be empty.\")\nelse:\n    print(f\"Parsing error: {parsed_doc.ErrorStr()} (ID: {parsed_doc.ErrorID()})\")\n\n# Example of saving to a file (optional, requires write access)\n# output_filename = \"output.xml\"\n# if os.environ.get('ENABLE_FILE_WRITE', '0') == '1': # Use env var for safety\n#     if doc.SaveFile(output_filename):\n#         print(f\"XML successfully saved to {output_filename}\")\n#     else:\n#         print(f\"Error saving XML to {output_filename}: {doc.ErrorStr()}\")\n","lang":"python","description":"This quickstart demonstrates how to create a new XML document, add elements, attributes, and text, and then print its content. It also shows how to parse an existing XML string and navigate its elements, including checking for parsing errors using TinyXML-2's error handling API."},"warnings":[{"fix":"Always check `doc.Error()` or `element.Error()` and `doc.ErrorStr()`/`ErrorID()` after operations that might fail (e.g., `Parse`, `LoadFile`, `SaveFile`, navigating non-existent elements).","message":"TinyXML-2 uses a C++-style error handling approach where methods return status codes or require explicit checks via `XMLDocument.Error()` or `XMLElement.Error()` after operations. Unlike Pythonic exceptions, you must explicitly check for errors, especially after parsing (`Parse`, `LoadFile`) or file operations (`SaveFile`).","severity":"gotcha","affected_versions":"All versions"},{"fix":"Verify file paths and permissions. Check `doc.Error()` after `LoadFile`/`SaveFile` to understand any I/O issues. Consider using `os.path.exists` or `try-except` blocks for general file system interactions.","message":"When loading or saving files using `LoadFile` and `SaveFile`, ensure the provided paths are valid and that your application has the necessary read/write permissions. File I/O errors will set the document's internal error state.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Review the upstream TinyXML-2 release notes and `cmeel-tinyxml2` GitHub repository for API changes when upgrading to a new major version. Thoroughly test your XML processing logic after an upgrade.","message":"Upgrading `cmeel-tinyxml2` might implicitly upgrade the underlying TinyXML-2 C++ library. While `cmeel` aims for stable bindings, major version bumps in TinyXML-2 (or `cmeel-tinyxml2`) could introduce API changes or subtle behavioral differences that break existing code.","severity":"breaking","affected_versions":"Any major version transition (e.g., 9.x to 10.x)"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Ensure the package is installed with `pip install cmeel-tinyxml2`. Verify that the import statement is `import tinyxml2`.","cause":"The `cmeel-tinyxml2` package is either not installed, or the `import` statement uses an incorrect module name.","error":"ModuleNotFoundError: No module named 'tinyxml2'"},{"fix":"Inspect the XML input for correctness. After `doc.Parse()` or `doc.LoadFile()`, always check `if doc.Error():` and print `doc.ErrorStr()` to get the specific reason for the parsing failure.","cause":"The XML string or file being parsed is malformed, empty, or lacks a valid root element, causing TinyXML-2 to report a parsing error.","error":"Document has no root element. (or similar error via doc.ErrorStr())"},{"fix":"Consult the quickstart or the `cmeel-tinyxml2` source/documentation for the correct PascalCase method names (e.g., `SetAttribute`, `Attribute`, `FirstChildElement`).","cause":"The Python bindings expose the C++ API directly. The method names are often in C++ PascalCase (`SetAttribute`, `FirstChildElement`) rather than Python snake_case (`set_attribute`, `first_child_element`).","error":"AttributeError: 'XMLElement' object has no attribute 'get_attribute'"}]}