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 namespacexmlns: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- Textw:br- Line breakw:tab- Tab characterw:drawing- Inline imagew:sym- Symbolw: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):
- Document Defaults (
w:docDefaultsin styles.xml) - Style (referenced via
w:pStyleorw:rStyle) - Direct Formatting (properties in
w:pProrw: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:
- Element Hierarchy Rules - Valid nesting rules
- Common Fatal Mistakes - What breaks documents
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!