Search code examples
xmlpascalhelpndoc

Using XPath to locate a node in a XML file with a HelpNDoc custom template


I am trying to enhance my HTML template that is used with HelpNDoc. One thing I find lacking is the fact that the meta description tag is the same for all pages.

The template file is a mixture of pascal and HTML. At the moment this is the data in the template for showing the description tag:

<meta name="description" content="<% print(HndProjects.GetProjectSummary()); %>" />

I have created a mapping XML document which contains the needed descriptions. Example:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<HelpTopics xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <Topic>
        <Caption>Overview</Caption>
        <ID>msa-overview</ID>
        <ContextID>0</ContextID>
        <Description>An introduction to Meeting Schedule Assistant.</Description>
    </Topic>
    <Topic>
        <Caption>Quick Start - Getting Started</Caption>
        <ID>msa-quick-start</ID>
        <ContextID>1</ContextID>
        <Description>A quick start guide to get you up and running with Meeting Schedule Assistant.</Description>
    </Topic>
    <Topic>
        <Caption>Using Meeting Schedule Assistant</Caption>
        <ID>msa</ID>
        <ContextID>2</ContextID>
        <Description>An overview of the menus in Meeting Schedule Assistant.</Description>
    </Topic>
</HelpTopics>

Is it possible, using pascal inside this HelpnDoc script to read the XML file? On their site they provide the details about the HndProjects and it mentions:

function GetProjectId: string;

Returns the currently open project id.

So I would basically like to get this value from the XML data file:

HelpTopics/Topic/ID[text()='<% HndProjects.GetProjectId(); %>'

But I don't know how to use such an XPath with a HelpNDoc Pascal script.

Update

I tried adding this code to get be going:

function GetDescription(sTopicID: string): String;
var
    nodeTopic: TDOMNode;
    doc: TXMLDocument;
begin
    try
        // Read in the xml file
        ReadXMLFile(doc, '.\MSA-Help-Descriptions.xml');
        // Get the node
        //nodeTopic := doc.DocumentElement.FindNode(
        // How do we get the node at:  HelpTopics/Topic/ID[text()=sTopicID];
    finally
        doc.Free;
    end;
    GetDescription := 'xxxx';
end;

Then, inside HelpNDoc I tried to compile the script but I got these errors:

Log

So I am not sure if I can even do what I want, unless I have missed some steps.


Solution

  • I had this feed back from the software authors:

    Please know that HelpNDoc's scripting engine is only a subset of the pascal language and libraries. There are no XML libraries available in the scripting language. It may be possible to use a third-party XML library but this is not something that we tested or support.

    We recommend that you work with simpler structures which can be easily parsed via simple code such as comma separated (CSV) files.

    Therefore, I created a simple text file where each line represents a meta description and the line number matches the context id of the help topic.

    Then I modified the pascal script that is used for compiling:

    function ReadFile(helpContextID: integer): string;
    var
        FText  : TStringList;
    begin
        FText := TStringList.Create;
        try
           FText.LoadFromFile('D:\My Programs\2017\MeetSchedAssist\HelpNDoc\HelpTopicDescriptions.txt');
           result := FText[helpContextID];
        finally
           FText.Free;
        end;
    end;
    

    Finally, I made the following call to set the meta description:

    <meta name="description" content="<% print(ReadFile(HndTopics.GetTopicHelpContext(HndGeneratorInfo.CurrentTopic))); %>" />
    

    Update

    For what it is worth, I improved the code by making the TStringList a global variable. Then I read in the data file into this list only once and use that in the creation of the meta descriptions. Finally, I free the list towards the end of the building process in the script file.