• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Verify References in a Ditamap - ExtendScript

Explorer ,
May 29, 2018 May 29, 2018

Copy link to clipboard

Copied

Hi Folks,

I wrote a script to verify if all the files referenced in a ditamap exist. The script is rather slow when the a ditamap refers to other ditamaps because the script opens those ditamaps.

var doc = app.FirstOpenDoc;

CheckDITATopicref(doc)

function CheckDITATopicref(doc) {

    var DITATopicref = doc.FirstDITATopicrefElementInDoc;

    while(DITATopicref.ObjectValid()) {

        var myFile = new File(DITATopicref.TopicRefAbsoluteFilePath);

        if (!(myFile.exists)) {

            $.writeln("The following file is missing: "+ DITATopicref.TopicRefAbsoluteFilePath)

        } else {

            if(DITATopicref.TopicRefAbsoluteFilePath.split(".")[DITATopicref.TopicRefAbsoluteFilePath.split(".").length-1] == "ditamap"){ //if file is ditamap

                var Topicref = Open(DITATopicref.TopicRefAbsoluteFilePath, GetOpenDefaultParams (), new PropVals());

                CheckDITATopicref (Topicref)

                Topicref.Close(Constants.FF_CLOSE_MODIFIED);

            }

        }

        DITATopicref = DITATopicref.NextDITATopicrefElementInDoc;

    }

}

I'm wondering if there are faster methods.

  1. Is opening the ditamap mandatory to do the verification?
  2. Do I need to loop through the topicrefs to find the missing ones?

Regards

TOPICS
Scripting

Views

438

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Advocate , May 29, 2018 May 29, 2018

Hello Fabian,

The answer is: yes, you need to open each dita map in order to check what topicrefs are inside. But no, you should not open them in FM as that adds a lot of processing steps that make it really slow. ExtendScript features XML support, as described in the JavaScript Tools Guide​. Check the chapter on using the XML object in that guide.

function ReadXML( filename )

{

    var xmlMap;

    var oFile = File( filename );

    if( oFile.open( 'r' ) )

    {

         sContents = oFile.read( oFile.le

...

Votes

Translate

Translate
Advocate ,
May 29, 2018 May 29, 2018

Copy link to clipboard

Copied

Hello Fabian,

The answer is: yes, you need to open each dita map in order to check what topicrefs are inside. But no, you should not open them in FM as that adds a lot of processing steps that make it really slow. ExtendScript features XML support, as described in the JavaScript Tools Guide​. Check the chapter on using the XML object in that guide.

function ReadXML( filename )

{

    var xmlMap;

    var oFile = File( filename );

    if( oFile.open( 'r' ) )

    {

         sContents = oFile.read( oFile.length );

         oFile.close( );

         xmlMap = new XML( sContents );

    }

    return xmlMap;

}

Processing the xml object is total luxury compared to anything else:

var xmlTopicRefs = xmlMap..topicref;       // the double colon enables retrieval of any <topicref> descendant.

for( i = 0; i < xmlTopicRefs.length( ); i++ )

{

     var sHref = xmlTopicRefs.@href.toString( );

     ... prepend the map's base path and check if the sHref points to an existing file ...

}

Note that the length property on an XML object does not exist - it is implemented as a length( ) function instead.

Also note that I have skipped the usual extensive error handling in the above code. You will be able to figure that out, no doubt.

Kind regards

Jang

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
May 29, 2018 May 29, 2018

Copy link to clipboard

Copied

Thank you Jang,

I used the codes from your answer and ran the script on a big file. Both versions took about 12 seconds. The commands you suggest are obviously more suitable but there is a thing I don't understand.

When using "oFile.open( 'r' )"  don't I open the file in FM anyway? Were you suggesting to use a standalone script?

Is the difference mainly in the memory usage? (I'm using the FM publishing server and I must process some files invisibly so the server does not crash)

Regards

Fabian

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
May 29, 2018 May 29, 2018

Copy link to clipboard

Copied

Jang's solution bypasses FrameMaker altogether. You are just using ExtendScript to process and check the XML files outside of FrameMaker.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
May 29, 2018 May 29, 2018

Copy link to clipboard

Copied

As Rick remarked but clarifying a bit more - opening the file as text in ExtendScript bypasses the rendering engine of FrameMaker, which also includes all kinds of cross-reference checking etc. As you are not interested in rendering unless all topicrefs point to actual files, running that check does not require opening the actual files.

BTW, if you are using the DITA-OT route to render the ditamap (which is an option in FrameMaker as well as the Fm Pub Server), Frame will not open the files at all, but run the DITA-OT transforms instead. But I am assuming you use the FrameMaker rendering engine for your output(s).

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
May 30, 2018 May 30, 2018

Copy link to clipboard

Copied

LATEST

Good afternoon gentlemen,

Thank you again. I'm pretty sure we are using the FrameMaker rendering engine, although I don't understand everything of what our scripts are doing.

Anyway, I made a mistake yesterday while implementing your suggestion. It is 200ms fast, not 12s like mine

Regards

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines