Skip to main content

WordprocessingML Core Elements

The Building Blocks of Document Content​

Every Word document is built from a small set of core XML elements. Master these, and you understand 80% of OOXML document structure.


Document Hierarchy​

The Golden Rule​

document → body → paragraphs → runs → text

Every piece of text in a Word document follows this hierarchy:

<w:document>
<w:body>
<w:p> ← Paragraph
<w:r> ← Run
<w:t>Hello</w:t> ← Text
</w:r>
</w:p>
</w:body>
</w:document>

Element 1: Document (w:document)​

Purpose: Root element of the main document content

Location: /word/document.xml

Structure:

<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
<w:body>
<!-- All content goes here -->
</w:body>
</w:document>

Key attributes:

  • xmlns:w - Main WordprocessingML namespace
  • xmlns:r - Relationships namespace (for IDs)

💡 Pro Tip: The document element always needs namespace declarations. Missing them = document won't open!


Element 2: Body (w:body)​

Purpose: Container for all document content

Parent: w:document

Children: Paragraphs, tables, content controls

Structure:

<w:body>
<w:p>...</w:p> <!-- Paragraphs -->
<w:tbl>...</w:tbl> <!-- Tables -->
<w:sdt>...</w:sdt> <!-- Content controls -->

<w:sectPr> <!-- Section properties (last element) -->
...
</w:sectPr>
</w:body>

Important: Section properties (w:sectPr) typically come at the end of the body.


Element 3: Paragraph (w:p) - Block-Level​

Purpose: Block-level container for text and inline elements

Analogy: Like a <p> tag in HTML - represents a paragraph break

Structure:

<w:p>
<w:pPr> <!-- Properties (optional) -->
<w:pStyle w:val="Normal"/>
<w:jc w:val="left"/>
</w:pPr>

<w:r> <!-- One or more runs -->
<w:t>Content</w:t>
</w:r>
</w:p>

Paragraph Anatomy​

Empty Paragraph​

Valid (used for spacing):

<w:p/>

Or with properties:

<w:p>
<w:pPr>
<w:spacing w:after="200"/> <!-- Space after paragraph -->
</w:pPr>
</w:p>

⚠️ Common Pitfall: Don't forget that every table cell must contain at least one paragraph, even if empty!


Element 4: Paragraph Properties (w:pPr)​

Purpose: Defines paragraph-level formatting

Parent: w:p (must be first child)

Common properties:

<w:pPr>
<!-- Style reference -->
<w:pStyle w:val="Heading1"/>

<!-- Alignment -->
<w:jc w:val="center"/> <!-- left, right, center, both (justified) -->

<!-- Indentation (in twips: 1/20 of a point) -->
<w:ind w:left="720" <!-- Left indent -->
w:right="720" <!-- Right indent -->
w:firstLine="360"/> <!-- First line indent -->

<!-- Spacing (in twips) -->
<w:spacing w:before="240" <!-- Space before -->
w:after="240" <!-- Space after -->
w:line="360" <!-- Line spacing -->
w:lineRule="auto"/> <!-- auto, atLeast, exact -->

<!-- Numbering (for lists) -->
<w:numPr>
<w:ilvl w:val="0"/> <!-- List level (0-8) -->
<w:numId w:val="1"/> <!-- Numbering instance ID -->
</w:numPr>

<!-- Keep with next paragraph -->
<w:keepNext/>

<!-- Page break before -->
<w:pageBreakBefore/>
</w:pPr>

AppraiSys Example​

From your DefaultDocument.cs:

var paragraphProperties = new ParagraphProperties();

// Center alignment
paragraphProperties.Append(new Justification {
Val = JustificationValues.Center
});

// Indentation (in twentieths of a point)
var indentation = new Indentation {
Left = "720", // 0.5 inch
Right = "720",
FirstLine = "360" // 0.25 inch
};
paragraphProperties.Append(indentation);

// Line spacing
var spacing = new SpacingBetweenLines {
Line = "360", // 1.5 line spacing
LineRule = LineSpacingRuleValues.Auto
};
paragraphProperties.Append(spacing);

🔗 See Also: Styles and Formatting


Element 5: Run (w:r) - Inline Container​

Purpose: Container for text with consistent formatting

Analogy: Like a <span> in HTML - inline text with specific formatting

Key concept: When formatting changes, you need a new run

Structure:

<w:r>
<w:rPr> <!-- Run properties (optional) -->
<w:b/> <!-- Bold -->
<w:i/> <!-- Italic -->
</w:rPr>

<w:t>Text</w:t> <!-- Text content -->
</w:r>

Multiple Runs in Practice​

<w:p>
<w:r>
<w:t>This is </w:t>
</w:r>

<w:r>
<w:rPr>
<w:b/> <!-- Bold -->
</w:rPr>
<w:t>bold</w:t>
</w:r>

<w:r>
<w:t> and this is </w:t>
</w:r>

<w:r>
<w:rPr>
<w:i/> <!-- Italic -->
</w:rPr>
<w:t>italic</w:t>
</w:r>

<w:r>
<w:t>.</w:t>
</w:r>
</w:p>

Result: "This is bold and this is italic."

What Can Go Inside a Run?​

  • w:t - Text
  • w:br - Line break
  • w:tab - Tab character
  • w:drawing - Inline image
  • w:sym - Symbol
  • w:footnoteReference - Footnote mark
  • Field codes

❌ Cannot go inside a run:

  • w:p - Paragraphs (block-level)
  • w:tbl - Tables (block-level)
  • w:sdt - Content controls (usually block-level)

Element 6: Run Properties (w:rPr)​

Purpose: Character-level formatting

Parent: w:r (must be first child)

Common properties:

<w:rPr>
<!-- Font -->
<w:rFonts w:ascii="Times New Roman"
w:hAnsi="Times New Roman"
w:eastAsia="Times New Roman"/>

<!-- Size (in half-points: 24 = 12pt) -->
<w:sz w:val="24"/>
<w:szCs w:val="24"/> <!-- Complex script size -->

<!-- Color (hex) -->
<w:color w:val="FF0000"/> <!-- Red -->

<!-- Formatting -->
<w:b/> <!-- Bold -->
<w:i/> <!-- Italic -->
<w:u w:val="single"/> <!-- Underline -->
<w:strike/> <!-- Strikethrough -->

<!-- Highlight -->
<w:highlight w:val="yellow"/>

<!-- Vertical alignment -->
<w:vertAlign w:val="superscript"/> <!-- or subscript -->

<!-- Character style -->
<w:rStyle w:val="Emphasis"/>
</w:rPr>

AppraiSys Example​

Creating styled text from your codebase:

var runProperties = new RunProperties();

// Font
runProperties.Append(new RunFonts {
Ascii = "Times New Roman",
HighAnsi = "Times New Roman"
});

// Size (12pt = 24 half-points)
runProperties.Append(new FontSize { Val = "24" });

// Color (Yale Blue for placeholders)
runProperties.Append(new Color { Val = "0B5394" });

// Bold
runProperties.Append(new Bold());

var run = new Run();
run.Append(runProperties);
run.Append(new Text("Placeholder text"));

Element 7: Text (w:t)​

Purpose: Contains actual text content

Parent: w:r (run)

Structure:

<w:t>Hello World</w:t>

Whitespace Handling​

Important attribute: xml:space="preserve"

Without it, leading/trailing spaces are stripped:

<w:t>Hello</w:t>  <!-- OK -->
<w:t> Hello </w:t> <!-- Spaces trimmed! Becomes "Hello" -->

With xml:space="preserve", spaces are kept:

<w:t xml:space="preserve"> Hello </w:t>  <!-- Keeps spaces -->
<w:t xml:space="preserve"> </w:t> <!-- Keeps multiple spaces -->

When to Use xml:space="preserve"​

Always use it when:

  • Text starts or ends with spaces
  • Text is only spaces
  • Preserving exact spacing matters

AppraiSys pattern:

var text = new Text("  Indented text  ") {
Space = SpaceProcessingModeValues.Preserve
};

⚠️ Common Pitfall: Forgetting xml:space="preserve" causes mysterious spacing issues!


Element 8: Line Break (w:br)​

Purpose: Forces a line break without starting a new paragraph

Parent: w:r

Types:

<!-- Regular line break (like Shift+Enter) -->
<w:br/>

<!-- Page break -->
<w:br w:type="page"/>

<!-- Column break -->
<w:br w:type="column"/>

<!-- Text wrapping break -->
<w:br w:type="textWrapping"/>

Example:

<w:p>
<w:r>
<w:t>Line 1</w:t>
</w:r>
<w:r>
<w:br/> <!-- Line break -->
</w:r>
<w:r>
<w:t>Line 2</w:t>
</w:r>
</w:p>

Result:

Line 1
Line 2

💡 Pro Tip: Use w:br for line breaks within a paragraph. Use separate w:p elements for actual paragraph breaks.


Element 9: Tab (w:tab)​

Purpose: Inserts a tab character

Parent: w:r

Structure:

<w:p>
<w:r>
<w:t>Name:</w:t>
</w:r>
<w:r>
<w:tab/> <!-- Tab -->
</w:r>
<w:r>
<w:t>John Doe</w:t>
</w:r>
</w:p>

Result: Name: John Doe


Properties Inheritance​

The Cascade​

Formatting follows this priority (lowest to highest):

  1. Document Defaults (w:docDefaults in styles.xml)
  2. Style (referenced via w:pStyle or w:rStyle)
  3. Direct Formatting (properties in w:pPr or w:rPr)

Example:

<!-- In styles.xml: Normal style defines 12pt Times New Roman -->
<w:style w:styleId="Normal">
<w:rPr>
<w:rFonts w:ascii="Times New Roman"/>
<w:sz w:val="24"/> <!-- 12pt -->
</w:rPr>
</w:style>

<!-- In document.xml: Paragraph uses Normal style -->
<w:p>
<w:pPr>
<w:pStyle w:val="Normal"/> <!-- Inherits 12pt Times New Roman -->
</w:pPr>

<w:r>
<w:rPr>
<w:b/> <!-- Direct formatting: adds bold -->
<w:sz w:val="28"/> <!-- Direct formatting: overrides to 14pt -->
</w:rPr>
<w:t>Text is bold, 14pt Times New Roman</w:t>
</w:r>
</w:p>

Complete Example: Formatted Paragraph​

<w:p>
<!-- Paragraph properties -->
<w:pPr>
<w:pStyle w:val="Normal"/>
<w:jc w:val="left"/>
<w:spacing w:before="120" w:after="120"/>
</w:pPr>

<!-- Run 1: Normal text -->
<w:r>
<w:t>The property is located at </w:t>
</w:r>

<!-- Run 2: Bold address -->
<w:r>
<w:rPr>
<w:b/>
</w:rPr>
<w:t>123 Main Street</w:t>
</w:r>

<!-- Run 3: Normal text -->
<w:r>
<w:t> in </w:t>
</w:r>

<!-- Run 4: Italic city -->
<w:r>
<w:rPr>
<w:i/>
</w:rPr>
<w:t>Springfield</w:t>
</w:r>

<!-- Run 5: Normal text with preserved space -->
<w:r>
<w:t xml:space="preserve">. </w:t>
</w:r>

<!-- Run 6: Colored value -->
<w:r>
<w:rPr>
<w:color w:val="0B5394"/> <!-- Yale Blue -->
</w:rPr>
<w:t>$450,000</w:t>
</w:r>

<!-- Run 7: Period -->
<w:r>
<w:t>.</w:t>
</w:r>
</w:p>

Result: "The property is located at 123 Main Street in Springfield. $450,000."


Common Patterns in AppraiSys​

Creating a Simple Paragraph​

var paragraph = new Paragraph();
var run = new Run();
var text = new Text("Hello World");

run.Append(text);
paragraph.Append(run);
body.Append(paragraph);

Creating a Styled Paragraph​

var paragraph = new Paragraph();

// Apply style
var paragraphProperties = new ParagraphProperties {
ParagraphStyleId = new ParagraphStyleId {
Val = "Normal"
}
};
paragraph.Append(paragraphProperties);

// Add content
var run = new Run(new Text("Content"));
paragraph.Append(run);

Creating Formatted Text​

var run = new Run();

// Bold, 14pt, Red
var runProperties = new RunProperties(
new Bold(),
new FontSize { Val = "28" }, // 14pt
new Color { Val = "FF0000" }
);
run.Append(runProperties);
run.Append(new Text("Important!"));

🔗 See Also: Creating Documents for more code examples


Element Order Matters!​

Correct Order in Paragraph​

<w:p>
<w:pPr>...</w:pPr> <!-- 1. Properties first -->
<w:r>...</w:r> <!-- 2. Then runs -->
<w:r>...</w:r>
</w:p>

Correct Order in Run​

<w:r>
<w:rPr>...</w:rPr> <!-- 1. Properties first -->
<w:t>Text</w:t> <!-- 2. Then content -->
</w:r>

❌ Wrong (properties after content):

<w:r>
<w:t>Text</w:t>
<w:rPr>...</w:rPr> <!-- ERROR: Properties must come first! -->
</w:r>

⚠️ This will cause validation errors and may corrupt the document!


Quick Reference: Element Hierarchy​

w:document (root)
└─ w:body
├─ w:p (paragraph - block)
│ ├─ w:pPr (properties - optional)
│ └─ w:r (run - inline)
│ ├─ w:rPr (properties - optional)
│ ├─ w:t (text)
│ ├─ w:br (line break)
│ ├─ w:tab (tab)
│ └─ w:drawing (image)
├─ w:tbl (table - block)
└─ w:sdt (content control - block or inline)

Next Steps​

You now understand the core elements. Next, learn about the namespaces that make it all work:

➡️ Next: Namespaces - Understanding w:, r:, wp:, and more

Also Review:


Test Your Understanding​

Question 1​

Can you have a w:t element directly inside a w:p?

Answer

No! Text (w:t) must always be inside a run (w:r). The structure is: w:p → w:r → w:t.

<!-- WRONG -->
<w:p>
<w:t>Text</w:t>
</w:p>

<!-- CORRECT -->
<w:p>
<w:r>
<w:t>Text</w:t>
</w:r>
</w:p>

Question 2​

When do you need xml:space="preserve" on a w:t element?

Answer

Use it when:

  • Text starts or ends with spaces: " Hello"
  • Text is only whitespace: " "
  • You need to preserve exact spacing

Without it, leading and trailing spaces are trimmed.

Question 3​

What's the difference between w:br and starting a new w:p?

Answer
  • w:br - Line break within the same paragraph (like Shift+Enter in Word)

    • Inherits paragraph formatting
    • No spacing before/after
  • New w:p - Actual paragraph break (like Enter in Word)

    • Can have different formatting
    • Includes spacing before/after paragraph

Use w:br for line breaks in addresses or poetry. Use w:p for conceptual paragraph breaks.


💡 Remember: Master these 9 core elements, and you control 80% of document content generation!