docx/table-basic

A 2x2 table with one text cell per cell.

Library verdicts: python-docx: — docxjs: pass

Metadata

Feature iddocx/table-basic
Formatdocx
Categoryblock-content
Spececma-376-5-part-1 § 17.4.38 w:tbl

XPath assertions

ID / partPredicateXPathpython-docxdocxjs
tbl-element-present
word/document.xml
exist
At least one <w:tbl> element must be present in the body.
//w:tbl
tbl-has-two-rows
word/document.xml
exist
The table must contain <w:tr> row children.
//w:tbl/w:tr
tbl-cell-a1-text
word/document.xml
exist
A cell containing the literal text 'A1' must be present in the table.
//w:tbl//w:tc//w:t[normalize-space()='A1']
tbl-cell-b2-text
word/document.xml
exist
A cell containing the literal text 'B2' must be present in the table.
//w:tbl//w:tc//w:t[normalize-space()='B2']

Render assertions

IDPredicateSelectorpython-docxdocxjs
table-cell-a1-renderedcss_selector/ match-text = A1
At least one rendered <td>/<th> inside a <table> under .docx-wrapper must contain the text 'A1'. (docxjs emits <table> with <td> for each cell.)
.docx-wrapper table td, .docx-wrapper table thpass
table-row-countcss_selector/ equal-count
The rendered table must have exactly 2 <tr> rows. Catches phantom rows from trailing empty <w:tr> elements or dropped rows.
.docx-wrapper table tr
table-cell-countcss_selector/ equal-count
The rendered 2x2 table must have exactly 4 cells. Catches dropped or duplicated cells the match-text assertion can't see.
.docx-wrapper table td, .docx-wrapper table th
table-cell-b1-renderedcss_selector/ match-text = ^B1$
Row 1 column 2 must contain exactly 'B1'. Catches content leaking between sibling cells.
.docx-wrapper table tr:nth-of-type(1) td:nth-of-type(2), .docx-wrapper table tr:nth-of-type(1) th:nth-of-type(2)
table-cell-a2-renderedcss_selector/ match-text = ^A2$
Row 2 column 1 must contain exactly 'A2'. Catches content leaking between rows.
.docx-wrapper table tr:nth-of-type(2) td:nth-of-type(1), .docx-wrapper table tr:nth-of-type(2) th:nth-of-type(1)
table-cell-b2-renderedcss_selector/ match-text = ^B2$
Row 2 column 2 must contain exactly 'B2'. Catches content leaking between cells.
.docx-wrapper table tr:nth-of-type(2) td:nth-of-type(2), .docx-wrapper table tr:nth-of-type(2) th:nth-of-type(2)
table-has-four-cellscss_selector/ equal-count
Exactly four rendered cells must exist. Fewer means cells were wrongly merged; more means a cell was duplicated.
.docx-wrapper table td, .docx-wrapper table th

Generator source

scripts/gen_table_basic.py

#!/usr/bin/env python3
"""Generate ``fixtures/docx/table-basic.docx``.

A minimal document exercising the ``w:tbl`` element. A 2x2 table whose
four cells contain the literals A1, B1, A2, B2. Satisfies the
assertions in ``features/docx/table-basic.json``.
"""

from __future__ import annotations

from pathlib import Path

from docx import Document

_REPO_ROOT = Path(__file__).resolve().parent.parent
_OUT = _REPO_ROOT / "fixtures" / "docx" / "table-basic.docx"


def main() -> int:
    doc = Document()
    table = doc.add_table(rows=2, cols=2)
    table.cell(0, 0).text = "A1"
    table.cell(0, 1).text = "B1"
    table.cell(1, 0).text = "A2"
    table.cell(1, 1).text = "B2"
    _OUT.parent.mkdir(parents=True, exist_ok=True)
    doc.save(_OUT, reproducible=True)
    print(_OUT)
    return 0


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

Manifest (expanded)

{
  "$schema": "../manifest.schema.json",
  "id": "docx/table-basic",
  "title": "Basic table (2x2)",
  "format": "docx",
  "category": "block-content",
  "summary": "A 2x2 table with one text cell per cell.",
  "spec": {
    "source": "ecma-376-5-part-1",
    "clause": "17.4.38",
    "element": "w:tbl",
    "rnc_reference": "spec/ecma-376-5/part-1/rnc/WordprocessingML.rnc",
    "xsd_reference": "spec/ecma-376-5/part-1/xsd/wml.xsd",
    "notes": "A table element <w:tbl> contains tblPr, tblGrid, and one or more <w:tr> row children. This fixture has exactly two rows with two cells each, filled with the literals A1/B1/A2/B2."
  },
  "fixtures": {
    "machine": "docx/table-basic",
    "office": "docx/table-basic"
  },
  "generator": {
    "python": "scripts/gen_table_basic.py"
  },
  "assertions": [
    {
      "id": "tbl-element-present",
      "part": "word/document.xml",
      "namespaces": {
        "w": "http://schemas.openxmlformats.org/wordprocessingml/2006/main"
      },
      "xpath": "//w:tbl",
      "must": "exist",
      "description": "At least one <w:tbl> element must be present in the body."
    },
    {
      "id": "tbl-has-two-rows",
      "part": "word/document.xml",
      "namespaces": {
        "w": "http://schemas.openxmlformats.org/wordprocessingml/2006/main"
      },
      "xpath": "//w:tbl/w:tr",
      "must": "exist",
      "description": "The table must contain <w:tr> row children."
    },
    {
      "id": "tbl-cell-a1-text",
      "part": "word/document.xml",
      "namespaces": {
        "w": "http://schemas.openxmlformats.org/wordprocessingml/2006/main"
      },
      "xpath": "//w:tbl//w:tc//w:t[normalize-space()='A1']",
      "must": "exist",
      "description": "A cell containing the literal text 'A1' must be present in the table."
    },
    {
      "id": "tbl-cell-b2-text",
      "part": "word/document.xml",
      "namespaces": {
        "w": "http://schemas.openxmlformats.org/wordprocessingml/2006/main"
      },
      "xpath": "//w:tbl//w:tc//w:t[normalize-space()='B2']",
      "must": "exist",
      "description": "A cell containing the literal text 'B2' must be present in the table."
    }
  ],
  "render_assertions": [
    {
      "id": "table-cell-a1-rendered",
      "kind": "css_selector",
      "selector": ".docx-wrapper table td, .docx-wrapper table th",
      "must": "match-text",
      "value": "A1",
      "description": "At least one rendered <td>/<th> inside a <table> under .docx-wrapper must contain the text 'A1'. (docxjs emits <table> with <td> for each cell.)"
    },
    {
      "id": "table-row-count",
      "kind": "css_selector",
      "selector": ".docx-wrapper table tr",
      "must": "equal-count",
      "count": 2,
      "description": "The rendered table must have exactly 2 <tr> rows. Catches phantom rows from trailing empty <w:tr> elements or dropped rows."
    },
    {
      "id": "table-cell-count",
      "kind": "css_selector",
      "selector": ".docx-wrapper table td, .docx-wrapper table th",
      "must": "equal-count",
      "count": 4,
      "description": "The rendered 2x2 table must have exactly 4 cells. Catches dropped or duplicated cells the match-text assertion can't see."
    },
    {
      "id": "table-cell-b1-rendered",
      "kind": "css_selector",
      "selector": ".docx-wrapper table tr:nth-of-type(1) td:nth-of-type(2), .docx-wrapper table tr:nth-of-type(1) th:nth-of-type(2)",
      "must": "match-text",
      "value": "^B1$",
      "description": "Row 1 column 2 must contain exactly 'B1'. Catches content leaking between sibling cells."
    },
    {
      "id": "table-cell-a2-rendered",
      "kind": "css_selector",
      "selector": ".docx-wrapper table tr:nth-of-type(2) td:nth-of-type(1), .docx-wrapper table tr:nth-of-type(2) th:nth-of-type(1)",
      "must": "match-text",
      "value": "^A2$",
      "description": "Row 2 column 1 must contain exactly 'A2'. Catches content leaking between rows."
    },
    {
      "id": "table-cell-b2-rendered",
      "kind": "css_selector",
      "selector": ".docx-wrapper table tr:nth-of-type(2) td:nth-of-type(2), .docx-wrapper table tr:nth-of-type(2) th:nth-of-type(2)",
      "must": "match-text",
      "value": "^B2$",
      "description": "Row 2 column 2 must contain exactly 'B2'. Catches content leaking between cells."
    },
    {
      "id": "table-has-four-cells",
      "kind": "css_selector",
      "selector": ".docx-wrapper table td, .docx-wrapper table th",
      "must": "equal-count",
      "count": 4,
      "description": "Exactly four rendered cells must exist. Fewer means cells were wrongly merged; more means a cell was duplicated."
    }
  ]
}

Fixture

Download table-basic.docx (18.7 KB)

Reference preview

Reference (machine, page 1 PNG)

docx/table-basic page 1 reference

Reference PDF


Download PDF Open in PDF.js

Spec notes

A table element <w:tbl> contains tblPr, tblGrid, and one or more <w:tr> row children. This fixture has exactly two rows with two cells each, filled with the literals A1/B1/A2/B2.