XML dokumentace z Dynamics AX do Wordu

Možná se vám také občas stane, že chcete do nějakého dokumentu přidat popis základních tříd nějakého řešení. Pokud píšete XML dokumentaci v kódu (a je opravdu velká chyba jestli ne), máte již popis hotový, jen je třeba ho dostat do cílového dokumentu. Musíte ručně projít třídy, zkopírovat dokumentační komentáře, odstranit z nich “\\\”, zalomení řádků, případné formátovací tagy… – nebo to celé zautomatizovat.

Přesně to dělá skript, který popisuji níže. Výsledkem je Wordový dokument s odstavci a styly:

Nejprve je třeba vyexportovat dokumentaci do souboru. Vytvořte v Dynamics AX AOT projekt a přidejte do něj všechny relevantní třídy. Pak na projektu klikněte pravým myšítkem a zvolte Add-Ins > Extract XML documentation. Otevře se dialogové okno, v kterém zašrktněte Documentation, zadejte jméno souboru a potvrďte tlačítkem OK.

Pak už je řada na skriptu, který je – jako obvykle – napsaný v PowerShellu. Ke stažení je zde, ve zbytku příspěvku ho projdu a popíšu.

Skript nejprve načte XML soubor s dokumentací (nastavte cestu na soubor, který jste vygenerovali z Dynamics AX) a vyhledá informace o třídách. Díky XPath je to hračka.

#Input file
[xml]$xml = (Get-Content ExportedDocumentation.xml)
#Extract nodes with types
$types = $xml.SelectNodes("doc/members/member[starts-with(@name,'T:')]")

Potom pro každou třídu vytvoří objekt s vlastnostmi ClassName, Summary a Remarks.

#Fill texts to object properties
$doc = $types | % {New-Object PSObject -Property @{
    ClassName = ($_.name).SubString(2) #Omit "T:"
    Summary = ExtractText $_.summary
    Remarks = ExtractText $_.remarks}}

Funkce ExtractText() vytáhne text z XML a trochu o upraví.

Function ExtractText($node)
{
    if ($node -is [System.Xml.XMLElement])
    {
        [string]$text = $node.InnerXml
    }
    else
    {
        [string]$text = $node
    }
    if ($text)
    {
        #Remove <c> and </c> tags
        $text = [Regex]::Replace($text, '</?c>', '')
        #Extract type name from <see cref=...> tag
        $text = [Regex]::Replace($text, '<see[ \n]*cref="[TM]:(?<ref>[a-zA-Z0-9_]*)"[ \n]*/>', '${ref}')
        #Remove line breaks and suppress repeated whitespaces
        $text = [Regex]::Replace($text, '[\n ]+', ' ')
        $text = $text.Trim()
    }
    return $text
}

Poslední část skriptu vezme získaná data a vytvoří Wordový dokument. Styly a vše ostatní si upravte podle aktuální potřeby.

#Create Word document
$word = New-Object -ComObject Word.Application
$word.Visible = $true
$range = $word.Documents.Add().Range()
 
foreach ($item in $doc)
{
    #Class name
    $range.Text = "Class $($item.ClassName)"
    $range.Style = "Heading 3"
    $range.InsertParagraphAfter()
    $range.SetRange($range.End, $range.End)
 
    if ($item.Summary)
    {
        #Summary
        $range.Text = $item.Summary
        $range.Style = "Normal"
        $range.InsertParagraphAfter()
        $range.SetRange($range.End, $range.End)
    }
 
    if ($item.Remarks)
    {
        #Remarks (title)
        $range.Text = "Remarks:"
        $range.Style = "Normal"
        $range.InsertParagraphAfter()
        $range.SetRange($range.End, $range.End)
 
        #Remarks (text)
        $range.Text = $item.Remarks
        $range.Style = "Emphasis"
        $range.InsertParagraphAfter()
        $range.SetRange($range.End, $range.End)
    }
}

Odkazy:
Skript ke stažení
MSDN: XML Documentation [AX 2012]