1. Purpose
This section describes Canon’s support for XML, HTML, JSON, and YAML formats, including canonicalization rules, format detection, and format-specific features.
For usage examples, see Ruby API, CLI, or RSpec documentation.
2. Overview
Canon provides unified canonicalization and comparison for four serialization formats. Each format has specific rules and defaults optimized for its typical usage.
This page provides an overview of format support. See the child pages for format-specific details:
-
XML Format - W3C C14N, namespace handling
-
HTML Format - HTML4/5 detection, rendering behavior
-
JSON Format - Sorted keys, type preservation
-
YAML Format - YAML specifics, anchors and aliases
3. Format detection
Canon automatically detects format based on file extensions:
| Extension | Format |
|---|---|
|
XML |
|
HTML |
|
JSON |
|
YAML |
You can override auto-detection by explicitly specifying the format:
# Ruby API
Canon.format(content, :xml)
# CLI
$ canon format file.txt --format xml
# Comparison
Canon::Comparison.equivalent?(doc1, doc2, format: :xml)
4. Format comparison matrix
| Feature | XML | HTML | JSON | YAML |
|---|---|---|---|---|
Canonicalization standard |
W3C C14N 1.1 |
Custom |
Custom |
YAML 1.2 |
Comment support |
Yes |
Yes |
No |
Yes |
Attribute/key ordering |
Ignored default |
Ignored default |
Strict default |
Strict default |
Default diff mode |
by_object |
by_line |
by_object |
by_object |
Whitespace handling |
Strict default |
Normalized default |
Strict default |
Strict default |
Namespace support |
Yes |
Limited (XHTML) |
No |
No |
5. Format defaults summary
Each format has sensible defaults based on typical usage:
| Dimension | XML | HTML | JSON | YAML |
|---|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
— |
— |
|
|
|
— |
— |
|
|
|
— |
— |
|
— |
— |
|
|
|
|
|
— |
|
Default diff mode:
* XML: :by_object (tree-based semantic diff)
* HTML: :by_line (line-based diff)
* JSON: :by_object (tree-based semantic diff)
* YAML: :by_object (tree-based semantic diff)
6. Match profiles by format
Canon provides predefined profiles optimized for each format. The same profile name has format-appropriate settings.
6.1. strict profile
Purpose: Character-perfect matching
Use when: Testing exact serializer output, verifying formatting compliance, character-perfect matching required.
6.2. rendered profile
Purpose: Browser-rendered equivalence (most relevant for HTML)
Use when: Comparing how content would render, ignoring formatting that doesn’t affect display.
7. Working with multiple formats
Canon’s unified API works consistently across all formats:
# Format any content
Canon.format(xml_content, :xml)
Canon.format(html_content, :html)
Canon.format(json_content, :json)
Canon.format(yaml_content, :yaml)
# Compare any format
Canon::Comparison.equivalent?(xml1, xml2)
Canon::Comparison.equivalent?(html1, html2)
Canon::Comparison.equivalent?(json1, json2)
Canon::Comparison.equivalent?(yaml1, yaml2)
# RSpec matchers
expect(actual_xml).to be_xml_equivalent_to(expected_xml)
expect(actual_html).to be_html_equivalent_to(expected_html)
expect(actual_json).to be_json_equivalent_to(expected_json)
expect(actual_yaml).to be_yaml_equivalent_to(expected_yaml)
8. Format-specific comparators
You can use format-specific comparator classes directly:
# XML comparator
Canon::Comparison::XmlComparator.equivalent?(xml1, xml2,
match: { attribute_order: :ignore }
)
# HTML comparator
Canon::Comparison::HtmlComparator.equivalent?(html1, html2,
match_profile: :rendered
)
# JSON comparator
Canon::Comparison::JsonComparator.equivalent?(json1, json2,
match: { key_order: :ignore }
)
# YAML comparator
Canon::Comparison::YamlComparator.equivalent?(yaml1, yaml2,
match: { comments: :ignore }
)