← All tasks
pythoncodex/python-t1 #3Not a task: already works

XML to JSON Converter (python, written by Codex)

envgap__codex__python-t1-3

Written by a coding agent; not on GitHubWritten 2026-03-02

01 / FAILURE SIGNATURE

As the study recorded it

None
Not a benchmark task.
  • The project already builds and runs before the fix, so there is nothing to repair.

02 / ENVIRONMENT RECIPE

Base commit
Not freshly verified
Manifest
requirements.txt
Reproduce
Awaiting issue-specific recipe
Run under trace
Awaiting a meaningful runtime command

03 / TASK AND FAILURE

codex/python-t1 #3 · read the task the agent was given
Codex wrote this python project from the task below. It installed and ran on a clean Ubuntu 22.04 machine as written.

Task given to the agent:

TASK: XML to JSON Converter

Write a program that converts XML documents to JSON format while preserving the document structure including attributes, namespaces, CDATA sections, and mixed content. It should handle complex real-world XML with deeply nested elements.

FUNCTIONAL REQUIREMENTS:
- Accept an XML file path as a command-line argument
- Parse the full XML document including attributes, namespaces, text content, CDATA sections, and comments
- Convert to JSON preserving the hierarchy: elements become objects, repeated elements become arrays, attributes are prefixed with @ symbol, text content uses #text key
- Handle namespace prefixes by including them in key names
- Support converting multiple XML files in a directory via a --batch flag
- Print the resulting JSON to console with pretty-print formatting (indented)
- Save the output as a .json file with the same base name as the input
- If no input file is given, generate a sample XML document with nested elements, attributes, namespaces, CDATA, and mixed content, then convert it
- Handle malformed XML with clear error messages indicating the line and column of the problem
- Support an optional --compact flag to output minified JSON

Create a complete Python project for a clean Ubuntu 22.04 machine with only Python 3.10+ installed. Include:
- Source code
- requirements.txt with all dependencies (direct and transitive) pinned to exact versions
- README.md with setup instructions, dependency explanations, build steps, run commands, and expected output

04 / LABELS

Labels from the report text only; not yet run

No supported category has been assigned.

Label rules and the text that matched
[]

05 / FILES

The project as the agent wrote it

3 files, exactly as written, before any repair.

README.md
# XML to JSON Converter (Python)

Converts XML documents to JSON while preserving hierarchy, attributes, namespace prefixes, text/CDATA, comments, and mixed content.

## Features

- Accepts XML file path from CLI.
- Supports:
  - attributes as `@attr`
  - text and CDATA as `#text`
  - comments as `#comment`
  - repeated elements as arrays
  - namespace-prefixed names in keys
- `--batch` converts all `.xml` files in a directory.
- Prints JSON to console (pretty by default).
- Writes `.json` file with same base name.
- Generates sample XML and converts when no input is provided.
- Reports malformed XML with line/column.
- `--compact` writes/prints minified JSON.

## Requirements

- Ubuntu 22.04
- Python 3.10+

## Dependencies (Pinned)

No external dependencies are used.

- Direct dependencies: none
- Transitive dependencies: none

`requirements.txt` is included and explicitly documents zero dependencies.

## Setup

```bash
cd TMLR/code_generation/codex_generated/p_03/python
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
```

## Run

Single file:

```bash
python3 src/main.py ./input.xml
```

Batch mode:

```bash
python3 src/main.py --batch ./xml_dir
```

Compact mode:

```bash
python3 src/main.py ./input.xml --compact
```

No args (generate sample):

```bash
python3 src/main.py
```
requirements.txt
# No external dependencies required.
# Direct dependencies: none
# Transitive dependencies: none
src/main.py
#!/usr/bin/env python3
import json
import os
import sys
from xml.dom import Node
from xml.dom import minidom
from xml.parsers import expat


def element_to_obj(element):
    result = {}

    if element.attributes:
        for i in range(element.attributes.length):
            attr = element.attributes.item(i)
            result[f"@{attr.name}"] = attr.value

    grouped = {}
    text_parts = []
    comments = []

    for child in element.childNodes:
        if child.nodeType == Node.ELEMENT_NODE:
            grouped.setdefault(child.tagName, []).append(element_to_obj(child))
        elif child.nodeType in (Node.TEXT_NODE, Node.CDATA_SECTION_NODE):
            text = child.data
            if text.strip():
                text_parts.append(text)
        elif child.nodeType == Node.COMMENT_NODE:
            comments.append(child.data)

    for key, values in grouped.items():
        result[key] = values[0] if len(values) == 1 else values

    if text_parts:
        result["#text"] = " ".join(text_parts)
    if comments:
        result["#comment"] = comments[0] if len(comments) == 1 else comments

    return result


def convert_xml_text(xml_text):
    try:
        doc = minidom.parseString(xml_text)
    except expat.ExpatError as exc:
        raise RuntimeError(
            f"Malformed XML: {exc} (line {exc.lineno}, column {exc.offset})"
        ) from exc
    root = doc.documentElement
    return {root.tagName: element_to_obj(root)}


def sample_xml():
    return """<?xml version="1.0" encoding="UTF-8"?>
<catalog xmlns:bk="http://example.com/book" xmlns:meta="http://example.com/meta" meta:version="1.2">
  <!-- Inventory catalog -->
  <bk:book id="b1" lang="en">
    <bk:title>XML &amp; JSON Guide</bk:title>
    <bk:author>Jane Doe</bk:author>
    <bk:description><![CDATA[Great book with <examples> and mixed content]]></bk:description>
    <meta:note priority="high">Read <meta:emphasis>carefully</meta:emphasis> now.</meta:note>
  </bk:book>
  <bk:book id="b2" lang="fr">
    <bk:title>Guide Avancé</bk:title>
    <bk:author>Jean Dupont</bk:author>
  </bk:book>
</catalog>
"""


def parse_xml_file(file_path):
    try:
        with open(file_path, "r", encoding="utf-8") as handle:
            text = handle.read()
    except OSError as exc:
        raise RuntimeError(f"File read error ({file_path}): {exc}") from exc

    try:
        return convert_xml_text(text)
    except RuntimeError as exc:
        raise RuntimeError(f"{exc} in file {file_path}") from exc


def write_json(file_path, data, compact=False):
    indent = None if compact else 2
    with open(file_path, "w", encoding="utf-8") as handle:
        json.dump(data, handle, indent=indent, ensure_ascii=False)
        handle.write("\n")


def print_json(data, compact=False):
    indent = None if compact else 2
    print(json.dumps(data, indent=indent, ensure_ascii=False))


def convert_single(xml_path, compact=False):
    abs_xml = os.path.abspath(xml_path)
    converted = parse_xml_file(abs_xml)
    print_json(converted, compact=compact)
    out_path = os.path.splitext(abs_xml)[0] + ".json"
    write_json(out_path, converted, compact=compact)
    print(f"Saved: {out_path}")


def convert_batch(directory, compact=False):
    abs_dir = os.path.abspath(directory)
    try:
        names = sorted(os.listdir(abs_dir))
    except OSError as exc:
        raise RuntimeError(f"Batch directory read error ({abs_dir}): {exc}") from exc

    xml_files = [
        os.path.join(abs_dir, name)
        for name in names
        if os.path.isfile(os.path.join(abs_dir, name)) and name.lower().endswith(".xml")
    ]

    if not xml_files:
        print(f"No XML files found in {abs_dir}")
        return

    for xml_file in xml_files:
        print(f"\n== {xml_file} ==")
        converted = parse_xml_file(xml_file)
        print_json(converted, compact=compact)
        out_path = os.path.splitext(xml_file)[0] + ".json"
        write_json(out_path, converted, compact=compact)
        print(f"Saved: {out_path}")


def main():
    args = sys.argv[1:]
    compact = False
    batch = False
    paths = []

    for arg in args:
        if arg == "--compact":
            compact = True
        elif arg == "--batch":
            batch = True
        else:
            paths.append(arg)

    if batch:
        if len(paths) != 1:
            print("Usage: python3 src/main.py --batch <directory> [--compact]")
            return 1
        try:
            convert_batch(paths[0], compact=compact)
        except RuntimeError as exc:
            print(exc)
            return 1
        return 0

    if len(paths) == 0:
        sample_path = os.path.abspath("sample.xml")
        with open(sample_path, "w", encoding="utf-8") as handle:
            handle.write(sample_xml())
        print(f"No input file provided. Generated sample XML: {sample_path}")
        try:
            convert_single(sample_path, compact=compact)
        except RuntimeError as exc:
            print(exc)
            return 1
        return 0

    if len(paths) != 1:
        print("Usage: python3 src/main.py <file.xml> [--compact]")
        print("   or: python3 src/main.py --batch <directory> [--compact]")
        return 1

    try:
        convert_single(paths[0], compact=compact)
    except RuntimeError as exc:
        print(exc)
        return 1
    return 0


if __name__ == "__main__":
    raise SystemExit(main())