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

To call xslt scripts developed inside ExtendScript

Community Beginner ,
Sep 01, 2023 Sep 01, 2023

xsl script have been developped, so I would like to call xsl scripts developed inside ExtendScript in order the users don't need to save .FM as .xml, then, run xslt script to transfter the other .xml format. Is it possible? 

 

Thanks.

 

1.8K
Translate
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

Community Expert , Sep 01, 2023 Sep 01, 2023

Here is a general purpose function that you can use to invoke an XSLT transform:

 

function runTransformation (transform) {
    
    /* transform is a JavaScript object:
       .xml = absolute path to the file to transform
       .xsl = absolute path to the XSL stylesheet
       .pro = XSLT processor (SAXON)
       .out = absolute path to the transformed file.
       .console = true to show the Console,
           false to suppress the Console
       .params = an array of objects containing
    
...
Translate
Community Expert ,
Sep 01, 2023 Sep 01, 2023

I suspect that Jang Graat will respond, but here is a link to one of his blog posts to get you started:

https://blog.adobe.com/en/publish/2017/11/21/xslt-support-in-framemaker-2017

If I have time later, I will post some example code. I use this feature extensively in my ExtendScript scripts to run XSLT stylesheets. FrameMaker has the Saxon Enterprise Edition built in and you can do a lot with it from your scripts.

Translate
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 Beginner ,
Sep 01, 2023 Sep 01, 2023

Thanks for your quick reply. 

I will be really  appreciate if you have time to post some example code in order for me to understand better and hand on  it quickly. Thanks again. 

 

 

Translate
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 Beginner ,
Sep 01, 2023 Sep 01, 2023

By the way, I have read that artical before and also followed steps to call CallClient() but nothting is happened .. so, I would like to have same example code to study how to make it work. One more question, should we change the setting of FrameMaker in the meanwhile? Thanks a lot. 

 

Translate
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 ,
Sep 01, 2023 Sep 01, 2023

Here is a general purpose function that you can use to invoke an XSLT transform:

 

function runTransformation (transform) {
    
    /* transform is a JavaScript object:
       .xml = absolute path to the file to transform
       .xsl = absolute path to the XSL stylesheet
       .pro = XSLT processor (SAXON)
       .out = absolute path to the transformed file.
       .console = true to show the Console,
           false to suppress the Console
       .params = an array of objects containing
           name/value pairs (optional)
    */
    
    var cmd, count, i, result;
    
    // Create the command string.
    cmd = 'XSLTRunTrScenario ' +  
        '-file \"' + transform.xml + '\" ' +
        '-xslfilepath \"' + transform.xsl + '\" ' +
        '-processor \"' + transform.pro + '\" ' +
        '-outputfilepath \"' + transform.out + '\"';
        
    // See if Console messages should be displayed.
    if (transform.console === false) {
        cmd += " -dontusefmconsole";
    }

    // Add any parameters to the command line.
    count = transform.params.length;
    for (i = 0; i < count; i += 1) {
        cmd += ' -sparam ' + transform.params[i].name + ' "' + 
            transform.params[i].value + '"';
    }

    // Invoke the transform.
    result = CallClient ("FmXSLT", cmd);
}

 

Translate
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 Beginner ,
Sep 05, 2023 Sep 05, 2023

Thanks  a lot for your general purpose code! now I got the "result = -1" which is better than before, returns something;-).

The command used is shown below (without params (Optional)),

<XSLTRunTrScenario
-file "C:\temp\chapters_structured.xml"

-xslfilepath "C:\temp\test.xsl"

-processor "SAXON"

-outputfilepath "C:\temp\chapters_structured_after.xml">

 

Is the command wrong? by the way, what should be set for "sparam"? Is it possible to explain a little bit about this with the example?  Thanks.

 

 

 

 

Translate
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 ,
Sep 05, 2023 Sep 05, 2023

You want to put all of your XSLTRunTrScenario into a string variable (without the angled brackets in your example) and then pass it to this call:

// Invoke the transform.
    result = CallClient ("FmXSLT", cmd);

where cmd is your string variable.

Translate
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 Beginner ,
Sep 05, 2023 Sep 05, 2023

"cmd" posted before is copied from data structure and I added < > that to show the command line, excuse me for the confustion.

Here is my whole code for this operation:

var transform = new Object();
transform.xml = "C:\temp\chapters_structured.xml";
transform.xsl = "C:\temp\test.xsl";
transform.pro = "SAXON"
transform.out = "C:\temp\chapters_structured_after.xml"
transform.console = true;

cmd = 'XSLTRunTrScenario ' +
'-file \"' + transform.xml + '\" ' +
'-xslfilepath \"' + transform.xsl + '\" ' +
'-processor \"' + transform.pro + '\" ' +
'-outputfilepath \"' + transform.out + '\"';

result = CallClient ("FmXSLT", cmd);
alert("CallClient result:" + result);

 

Translate
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 ,
Sep 05, 2023 Sep 05, 2023

Everything looks correct. A couple of things to check: Are you getting any messages to the Console window? Also, I would put this in my code:

Console (cmd);

so you can check your command line string for correctness; for example, matching quotes, etc. Add this to your code and post the Console message here. Thanks.

Translate
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 Beginner ,
Sep 06, 2023 Sep 06, 2023

It works now 🙂 The root cause is that I made a mistake which the output file wasn't created before calling CallClient() ... thanks a lot again for your advices and quick responses 🙂

 

 

Translate
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 ,
Sep 05, 2023 Sep 05, 2023

sparam is an optional set of name/value pairs for passing parameters to your stylesheet.

Translate
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 Beginner ,
Sep 06, 2023 Sep 06, 2023

Got it.

By the way, result still returns "-1" even when "Transformation Successful" is printed in Console window. Any idea? Thanks a lot. 

 

 

Translate
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 ,
Sep 06, 2023 Sep 06, 2023

FrameMaker API clients can have an integer return value and 0 is typically returned for success. Apparently, not all API clients are programmed this way, so I generally ignore the return value. As far as I know, there is no public documentation for the FmXSLT client, although I have requested documentation from Adobe. Here is a screenshot from the FDK Reference that may be helpful:

image.pngexpand image

Translate
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
New Here ,
Jun 09, 2024 Jun 09, 2024

Hello FrameExpert and Cheng-T,

I tried following your 'general purpose function' and Cheng-T's example, but unfortunately I reached an error at  'CallClient(). I will appreciate some pointers as to what I'm doing wrong. This is my code:

---

var xml_file= "C:\\Users\\RoyMontgomerie\\Documents\\WebPages\\READ_XML_TEST_SOURCE\\TESTSOURCE.xml";
var xml_AFTER_FILE= new File("C:\\Users\\RoyMontgomerie\\Documents\\WebPages\\READ_XML_TEST_SOURCE\\TESTSOURCEAFTER.xml");

var transform = new Object();
transform.xml =xml_file;
transform.xsl = "C:\\Users\\RoyMontgomerie\\Documents\\WebPages\\TESTXML\\TEST20XSLT.xslt";
transform.pro = "SAXON"
transform.out = xml_AFTER_FILE;
transform.console = true;

function runTransformation (transform) {

cmd = 'XSLTRunTrScenario ' +
'-file \"' + transform.xml + '\" ' +
'-xslfilepath \"' + transform.xsl + '\" ' +
'-processor \"' + transform.pro + '\" ' +
'-outputfilepath \"' + transform.out + '\"';

result = CallClient ("FmXSLT", cmd);
alert("CallClient result:" + result);

transform.console = true;

$.writeln (cmd);
result = CallClient ("FmXSLT", cmd);
alert("CallClient result:" + result);

};

runTransformation (transform);

--

 

 

Translate
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 ,
Jun 09, 2024 Jun 09, 2024

Try dropping the trailing backslash after the transform.out parameter.

Translate
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 Beginner ,
Jun 10, 2024 Jun 10, 2024

As FrameExpert said, transform.out is wrong. Here transform.out should be "String" instead of "File". 

Translate
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 ,
Jun 10, 2024 Jun 10, 2024

Good catch; I missed that. You can use transform.out.fsName to get the path string.

Translate
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
New Here ,
Jun 10, 2024 Jun 10, 2024

Hello FrameExpert and Cheng-T, 

I appreciate the help and have tried to update the code to match your suggestions but it still fails at 'CallClient(...)" . I turned the 'transform.xml' and 'transform.out' into strings. This is the newer code:


//Path names as strings
var xml_file= "C:\...\WebPages\READ_XML_TEST_SOURCE\TESTSOURCE.xml";
var xml_AFTER_FILE= "C:\...\WebPages\READ_XML_TEST_SOURCE\TESTSOURCEAFTER.xml";

//Create the transform object
var transform = new Object();
transform.xml =xml_file;
transform.xsl = "C:\......\1_Adobe_Structure\xml\DITA_1.3\app\technicalContent\xslt\TEST20XSLT.xsl";
transform.pro = "SAXON";
transform.out = xml_AFTER_FILE;

//create cmd for the CallClient
cmd = 'XSLTRunTrScenario ' +
'-file \" ' + transform.xml + '\" ' +
'-xslfilepath \"' + transform.xsl + '\" ' +
'-processor \"' + transform.pro + '\" ' +
'-outputfilepath \" ' + transform.out +' " ';

//CallClient
var result = CallClient ("FmXSLT", cmd);
alert("CallClient result:" + result);

transform.console = true;

$.writeln (cmd);
result = CallClient ("FmXSLT", cmd);
alert("CallClient result:" + result);

 

 

Translate
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 Beginner ,
Jun 10, 2024 Jun 10, 2024

transform.out should be "String",  but the corresponding output file has to be created before calling.

so, you just add one line before calling.

var xml_output_file = new File(xml_AFTER_FILE); 

 

 

Translate
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
New Here ,
Jul 01, 2024 Jul 01, 2024

Hello again,

I tried your tips and wrote the following code which still does not work:

I receive a 'CallClient result:-1' script alert.  I will be grateful for your input.

---

//Path names as strings
var xml_file= "C:\\Users\\XYZ\\Documents\\WebPages\\READ_XML_TEST_SOURCE\\TESTSOURCE.xml";
var xml_AFTER_FILE= "C:\\Users\\XYZ\\Documents\\WebPages\\READ_XML_TEST_SOURCE";

//Create the transform object
var transform = new Object();
transform.xml =xml_file;
transform.xsl = "C:\\Users\\XYZ\\Documents\\1_Adobe_Structure\\xml\\DITA_1.3\\app\\technicalContent\\xslt\\TEST20_TRY11.xsl";
transform.pro = "SAXON";
transform.out = xml_AFTER_FILE;
var xml_output_file = new File(xml_AFTER_FILE); // Corresponding output file created before calling 'CallClient()'

//create cmd for the CallClient
cmd = 'XSLTRunTrScenario ' +
'-file \" ' + transform.xml + '\" ' +
'-xslfilepath \"' + transform.xsl + '\" ' +
'-processor \"' + transform.pro + '\" ' +
'-outputfilepath \ "' + transform.out; // As FrameExpert suggested I have removed the '\'

//CallClient
var result = CallClient ("FmXSLT", cmd);
alert("CallClient result:" + result);

transform.console = true;

$.writeln (cmd);
result = CallClient ("FmXSLT", cmd);
alert("CallClient result:" + result);

 

Translate
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 ,
Jul 01, 2024 Jul 01, 2024

Please post the Console output, which should show the command line string.

Translate
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
New Here ,
Jul 02, 2024 Jul 02, 2024

Hi 

This is the console output:

XSLTRunTrScenario -file " C:\Users\RoyMontgomerie\Documents\WebPages\READ_XML_TEST_SOURCE\TESTSOURCE.xml" -xslfilepath "C:\Users\RoyMontgomerie\Documents\1_Adobe_Structure\xml\DITA_1.3\app\technicalContent\xslt\TEST20_TRY11.xsl" -processor "SAXON" -outputfilepath "C:\Users\RoyMontgomerie\Documents\WebPages\READ_XML_TEST_SOURCE
Result: undefined

There is an alert as well:

roym76266846_0-1719906395047.pngexpand image

Cheers

 

Translate
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 Beginner ,
Jul 02, 2024 Jul 02, 2024

cmd = 'XSLTRunTrScenario ' +
'-file \" ' + transform.xml + '\" ' +
'-xslfilepath \"' + transform.xsl + '\" ' +
'-processor \"' + transform.pro + '\" ' +
'-outputfilepath \ "' + transform.out+ '\" '; 

 

+ '\" ' is missing in your command.

Translate
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 ,
Jul 02, 2024 Jul 02, 2024

I am sorry, I gave you the wrong information about removing the last '\"'. That actually provides the closed double-quote for the outputfilepath parameter. So you need it, like @Cheng-T says. Also, you need to provide a file path, not just a folder path. For example, C:\Users\RoyMontgomerie\Documents\WebPages\READ_XML_TEST_SOURCE\outputfile.xml.

Translate
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
New Here ,
Jul 02, 2024 Jul 02, 2024

Hello  Frameexpert,

No problem.  I am glad you are helping me. 

I altered my ExtendScript and added the + '\" ' and included an output file name. I also had to create a File object for the output file so that I could open("w") and close() it (otherwise the file is not created):

---- code snippet ---

//CallClient
xml_output_file.open("w");
var result = CallClient("FmXSLT", cmd);
alert("CallClient result:" + result);
xml_output_file.close();

---- code snippet ---

So, the output is created but it is empty after calling 'CallClient("FmXSLT", cmd)'. 

The call result = '-1';

So the CallClient is being called but no XSLT transformation is taking place.

The transform I am using works well on MS Visual Studio with XML source files and through FrameMakers>XSLT>Advanced Run option.  

Pasted below is my source code, I will be grateful for your further input:

--- code begin ----

//Path names as strings
var xml_file= "C:\\Users\\DIR\\Documents\\WebPages\\READ_XML_TEST_SOURCE\\TEST_XYZ3.xml";
var xml_AFTER_FILE= "C:\\Users\\DIR\\Documents\\WebPages\\READ_XML_TEST_SOURCE\\newXML5.xml";
var xml_src_file = new File(xml_file); //Not sure this makes adifference to open it for reading but thought I would give it a try.
xml_src_file.open("r");
var xml_output_file = new File(xml_AFTER_FILE); // Corresponding output file created before calling 'CallClient()'
//Create the transform object
var transform = new Object();
transform.xml =xml_file;
transform.xsl = "C:\\Users\\DIR\\Documents\\WebPages\\READ_XML_TEST_SOURCE\\TEST20_TRY13.xsl";
transform.pro = "SAXON";
transform.out = xml_AFTER_FILE;
var xml_xsl_file = new File("C:\\Users\\DIR\\Documents\\WebPages\\READ_XML_TEST_SOURCE\\TEST20_TRY13.xsl"); // Creating a readable XSL file but not sure if necessary to do this.
xml_xsl_file.open("r");

//create cmd for the CallClient
cmd = 'XSLTRunTrScenario ' +
'-file \" ' + transform.xml + '\" ' +
'-xslfilepath \"' + transform.xsl + '\" ' +
'-processor \"' + transform.pro + '\" ' +
'-outputfilepath \ "' + transform.out+ '\" ';

//CallClient
xml_output_file.open("w");
var result = CallClient("FmXSLT", cmd);
alert("CallClient result:" + result);
xml_output_file.close();
transform.console = true;

$.writeln (cmd);

--- cdoe end ---

Please advise 

Thanks

 

Translate
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