Xml2Doc.MSBuild 2.3.0

dotnet add package Xml2Doc.MSBuild --version 2.3.0
                    
NuGet\Install-Package Xml2Doc.MSBuild -Version 2.3.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Xml2Doc.MSBuild" Version="2.3.0">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Xml2Doc.MSBuild" Version="2.3.0" />
                    
Directory.Packages.props
<PackageReference Include="Xml2Doc.MSBuild">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Xml2Doc.MSBuild --version 2.3.0
                    
#r "nuget: Xml2Doc.MSBuild, 2.3.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Xml2Doc.MSBuild@2.3.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Xml2Doc.MSBuild&version=2.3.0
                    
Install as a Cake Addin
#tool nuget:?package=Xml2Doc.MSBuild&version=2.3.0
                    
Install as a Cake Tool

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.0dotnet SDK 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 claims index.md in the aggregate output; disable its normal generation or set Xml2Doc_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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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
Loading failed