Xml2Doc.MSBuild
2.3.0
dotnet add package Xml2Doc.MSBuild --version 2.3.0
NuGet\Install-Package Xml2Doc.MSBuild -Version 2.3.0
<PackageReference Include="Xml2Doc.MSBuild" Version="2.3.0"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
<PackageVersion Include="Xml2Doc.MSBuild" Version="2.3.0" />
<PackageReference Include="Xml2Doc.MSBuild"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
paket add Xml2Doc.MSBuild --version 2.3.0
#r "nuget: Xml2Doc.MSBuild, 2.3.0"
#:package Xml2Doc.MSBuild@2.3.0
#addin nuget:?package=Xml2Doc.MSBuild&version=2.3.0
#tool nuget:?package=Xml2Doc.MSBuild&version=2.3.0
Xml2Doc.MSBuild
MSBuild integration for Xml2Doc, part of the mod-posh organization.
Overview
Xml2Doc.MSBuild converts compiler-generated C# XML documentation into Markdown automatically during a build.
Version 2.3.0 supports two models:
- normal per-project generation from one compiler XML file;
- repository aggregation, where one owner project renders multiple participating projects into one deterministic documentation set and one unified index.
Task hosts
The package contains task assemblies for:
net472— Visual Studio 2022 / full-framework MSBuild hosts;net8.0—dotnetSDK MSBuild hosts.
The package selects the appropriate task assembly automatically. Generated Markdown is expected to remain equivalent across supported task hosts for the same inputs and options.
Install
<ItemGroup>
<PackageReference Include="Xml2Doc.MSBuild" Version="2.3.0" PrivateAssets="all" />
</ItemGroup>
Projects that contribute compiler XML must enable:
<PropertyGroup>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
Normal project generation
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<Xml2Doc_Enabled>true</Xml2Doc_Enabled>
<Xml2Doc_OutputDir>$(MSBuildProjectDirectory)\docs</Xml2Doc_OutputDir>
<Xml2Doc_FileNameMode>clean</Xml2Doc_FileNameMode>
<Xml2Doc_LineEndings>lf</Xml2Doc_LineEndings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Xml2Doc.MSBuild" Version="2.3.0" PrivateAssets="all" />
</ItemGroup>
</Project>
Normal-generation properties
| Property | Default | Description |
|---|---|---|
Xml2Doc_Enabled |
true |
Enable or disable normal per-project generation. |
Xml2Doc_SingleFile |
false |
Generate one combined file instead of per-type files. |
Xml2Doc_OutputFile |
$(MSBuildProjectDirectory)\docs\api.md |
Single-file output path. |
Xml2Doc_OutputDir |
$(MSBuildProjectDirectory)\docs |
Per-type output directory. |
Xml2Doc_GenerateIndex |
true |
Generate index.md in per-type mode. |
Xml2Doc_FileNameMode |
clean |
clean or verbatim. |
Xml2Doc_RootNamespaceToTrim |
Empty | Namespace prefix trimmed from display names. |
Xml2Doc_TrimRootNamespaceInFileNames |
false |
Also trim the root namespace from filenames. |
Xml2Doc_CodeBlockLanguage |
csharp |
Fenced-code language. |
Xml2Doc_AnchorAlgorithm |
default |
default, github, gfm, or kramdown. |
Xml2Doc_Toc |
false |
Emit member tables of contents. |
Xml2Doc_NamespaceIndex |
false |
Emit namespace index output. |
Xml2Doc_BasenameOnly |
false |
Use basename-only output names/links. |
Xml2Doc_ParallelDegree |
1 |
Maximum per-type render parallelism. |
Xml2Doc_PruneStaleFiles |
false |
Remove stale output owned by this invocation. Per-type mode only. |
Xml2Doc_ManifestIdentity |
Empty | Stable identity required for stale pruning. |
Xml2Doc_LineEndings |
lf |
lf, crlf, or native. |
Xml2Doc_ReportPath |
$(Xml2Doc_OutputDir)\xml2doc-report.json |
JSON report path. |
Xml2Doc_ReportIncludeTimestamp |
false |
Include a report timestamp. |
Xml2Doc_DryRun |
false |
Plan without writing Markdown. |
Xml2Doc_Diff |
false |
Reserved; currently no effect in the MSBuild task. |
Xml2Doc_Dump |
false |
Log evaluated generation paths/settings. |
Xml2Doc_LogChosenTask |
false |
Log selected task TFM/assembly. |
Xml2Doc_Toc, Xml2Doc_NamespaceIndex, and Xml2Doc_BasenameOnly are assigned by package defaults. When enabling them globally, set them in the project file or Directory.Build.targets rather than relying on an earlier Directory.Build.props value.
Referenced XML for <inheritdoc />
XML documentation beside resolved project-reference assemblies is loaded automatically for inheritance lookup without generating pages for those referenced symbols.
Additional reference XML can be supplied explicitly:
<ItemGroup>
<Xml2Doc_ReferenceXml Include="path\to\Contracts.xml" />
</ItemGroup>
Reference XML participates in incremental fingerprinting. Missing explicit reference files and unresolved inheritance targets are reported as warnings.
Repository aggregation owner
Use one small project as the owner when multiple projects contribute to one documentation set:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<GenerateDocumentationFile>false</GenerateDocumentationFile>
<Xml2Doc_Enabled>false</Xml2Doc_Enabled>
<Xml2Doc_AggregateEnabled>true</Xml2Doc_AggregateEnabled>
<Xml2Doc_OutputDir>$(MSBuildProjectDirectory)\..\docs\api</Xml2Doc_OutputDir>
<Xml2Doc_FileNameMode>clean</Xml2Doc_FileNameMode>
<Xml2Doc_LineEndings>lf</Xml2Doc_LineEndings>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Alpha\Alpha.csproj" />
<ProjectReference Include="..\Zulu\Zulu.csproj" />
<PackageReference Include="Xml2Doc.MSBuild" Version="2.3.0" PrivateAssets="all" />
</ItemGroup>
</Project>
Every participating project must emit compiler XML:
<PropertyGroup>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
When the owner builds, Xml2Doc_Aggregate resolves project references, derives their XML documentation paths, canonicalizes the primary inputs, loads them through Core aggregation, and renders one output set.
If an expected primary XML file is missing, aggregation fails rather than silently producing incomplete documentation.
Explicit primary aggregate inputs
Inputs that are not project references can be added with Xml2Doc_AggregateXml:
<ItemGroup>
<Xml2Doc_AggregateXml Include="$(RepoRoot)\artifacts\External.Contracts.xml" />
</ItemGroup>
Xml2Doc_AggregateXml creates documentation pages. Xml2Doc_ReferenceXml remains reference-only and is used for inheritance/reference resolution.
Index ownership
The aggregation owner should be the only invocation that writes the aggregate index.md.
The cleanest participant configuration is:
<PropertyGroup>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<Xml2Doc_Enabled>false</Xml2Doc_Enabled>
</PropertyGroup>
If a participant still generates its own type pages into the same directory, delegate index ownership:
<PropertyGroup>
<Xml2Doc_GenerateIndex>false</Xml2Doc_GenerateIndex>
</PropertyGroup>
With project-reference participants, Xml2Doc_AggregateValidateIndexOwnership checks for conflicting index ownership before normal referenced-project builds begin. A conflicting participant fails with XML2DOC007 and identifies the project/output path.
Set Xml2Doc_AggregateValidateIndexOwnership=false only when higher-level orchestration already guarantees exclusive ownership.
Aggregate properties
| Property | Default | Description |
|---|---|---|
Xml2Doc_AggregateEnabled |
false |
Make this project the repository aggregation owner. |
Xml2Doc_AggregateValidateIndexOwnership |
true |
Validate referenced projects do not also own the aggregate index. |
Xml2Doc_AggregateReportPath |
$(Xml2Doc_OutputDir)\xml2doc-aggregate-report.json |
Aggregate report path. |
Xml2Doc_AggregateOutputStamp |
$(IntermediateOutputPath)xml2doc.aggregate.stamp |
Aggregate successful-generation stamp. |
Xml2Doc_AggregateFingerprintFile |
$(IntermediateOutputPath)xml2doc.aggregate.fingerprint.txt |
Aggregate input/options fingerprint. |
Xml2Doc_AggregateOutputLedger |
$(IntermediateOutputPath)xml2doc.aggregate.outputs.txt |
Aggregate generated-file ledger. |
The aggregation owner reuses normal renderer properties such as output mode, output paths, filename mode, root namespace trimming, anchor algorithm, index generation, pruning, manifest identity, parallelism, and line endings.
Aggregate primary input identities and explicit reference XML identities participate in fingerprinting. Primary/reference files are MSBuild target inputs, so changing the XML, participation, significant rendering options, or a recorded generated file causes regeneration. With Xml2Doc_LineEndings=native, the host newline policy also participates in the fingerprint.
Determinism
Core sorts aggregate inputs canonically and combines symbols in stable ordinal order. The aggregate report records the canonical primary list as xmlInputs.
Repository integration tests build the same owner with normal parallel scheduling and with /m:1, on Windows and Linux, and require identical generated file sets and identical bytes.
If two primary XML inputs define the same documentation member, generation fails with XML2DOC006 rather than choosing an owner based on input order.
Stale output and lifecycle files
For normal per-project generation, Xml2Doc_OutputStamp, Xml2Doc_FingerprintFile, and Xml2Doc_OutputLedger default under IntermediateOutputPath.
Aggregation uses separate xml2doc.aggregate.* lifecycle files so the repository owner has one independent incremental state boundary.
Stale Markdown pruning is supported only in per-type mode and requires a stable Xml2Doc_ManifestIdentity. Xml2Doc removes only paths recorded for that identity.
Line endings
Generated Markdown uses LF on every platform by default:
<PropertyGroup>
<Xml2Doc_LineEndings>lf</Xml2Doc_LineEndings>
</PropertyGroup>
Use crlf only when required by a downstream consumer. Use native only when host-specific bytes are intentional.
Conditional generation
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
<Xml2Doc_Enabled>true</Xml2Doc_Enabled>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)' != 'Release'">
<Xml2Doc_Enabled>false</Xml2Doc_Enabled>
</PropertyGroup>
CI
Normal project build:
dotnet build .\src\MyLibrary\MyLibrary.csproj -c Release
Repository aggregation owner:
dotnet build .\docs\ApiDocs.csproj -c Release
Troubleshooting
- No files produced: ensure the relevant project emits XML documentation with
GenerateDocumentationFile=true. - Aggregate input missing: ensure every participating project emits XML documentation and is included by project reference or
Xml2Doc_AggregateXml. XML2DOC006: two primary aggregate inputs document the same member ID; fix the input boundary.XML2DOC007: a referenced project still claimsindex.mdin the aggregate output; disable its normal generation or setXml2Doc_GenerateIndex=false.- Unexpected task load failure: use the current package and inspect the selected task with
<Xml2Doc_LogChosenTask>true</Xml2Doc_LogChosenTask>.
For the repository-owner pattern in more detail, see docs/msbuild-repository-aggregation.md.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Framework | net472 is compatible. net48 was computed. net481 was computed. |
This package has no dependencies.
NuGet packages (2)
Showing the top 2 NuGet packages that depend on Xml2Doc.MSBuild:
| Package | Downloads |
|---|---|
|
Yaml2Doc.Markdown
Renderer library that converts the neutral pipeline model into human-friendly Markdown documentation. |
|
|
Yaml2Doc.Core
Core library for parsing pipeline YAML into a neutral model for documentation. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2.3.0 | 129 | 8/17/2026 |
| 2.2.0 | 137 | 8/17/2026 |
| 2.1.0 | 213 | 8/16/2026 |
| 2.0.3 | 185 | 8/15/2026 |
| 2.0.2 | 193 | 8/14/2026 |
| 2.0.1 | 102 | 8/14/2026 |
| 2.0.0 | 102 | 8/13/2026 |
| 2.0.0-preview.113-g69c1a44 | 51 | 8/13/2026 |
| 1.4.0 | 123 | 8/13/2026 |
| 1.4.0-preview.111-g7a5369b | 55 | 8/13/2026 |
| 1.4.0-preview.110-g1edd8f0 | 60 | 8/13/2026 |
| 1.4.0-preview.109-g42abc6e | 53 | 8/13/2026 |
| 1.4.0-preview.108-g611e3f5 | 51 | 8/13/2026 |
| 1.4.0-preview.107-gc4dc99b | 57 | 8/13/2026 |
| 1.4.0-preview.106-gffe4bab | 54 | 8/13/2026 |
| 1.4.0-preview.105-gd9e6cf3 | 58 | 8/13/2026 |
| 1.4.0-preview.104-gfa11148 | 51 | 8/13/2026 |
| 1.4.0-preview.103-gc413f43 | 46 | 8/13/2026 |
| 1.4.0-preview.102-g7ed4c9f | 61 | 8/13/2026 |
| 1.4.0-preview.101-g1fbacd3 | 60 | 8/1/2026 |