Copy link to clipboard
Copied
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.
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
...
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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);
}
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
"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);
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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 🙂
Copy link to clipboard
Copied
sparam is an optional set of name/value pairs for passing parameters to your stylesheet.
Copy link to clipboard
Copied
Got it.
By the way, result still returns "-1" even when "Transformation Successful" is printed in Console window. Any idea? Thanks a lot.
Copy link to clipboard
Copied
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:
Copy link to clipboard
Copied
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);
--
Copy link to clipboard
Copied
Try dropping the trailing backslash after the transform.out parameter.
Copy link to clipboard
Copied
As FrameExpert said, transform.out is wrong. Here transform.out should be "String" instead of "File".
Copy link to clipboard
Copied
Good catch; I missed that. You can use transform.out.fsName to get the path string.
Copy link to clipboard
Copied
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);
Copy link to clipboard
Copied
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);
Copy link to clipboard
Copied
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);
Copy link to clipboard
Copied
Please post the Console output, which should show the command line string.
Copy link to clipboard
Copied
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:
Cheers
Copy link to clipboard
Copied
cmd = 'XSLTRunTrScenario ' +
'-file \" ' + transform.xml + '\" ' +
'-xslfilepath \"' + transform.xsl + '\" ' +
'-processor \"' + transform.pro + '\" ' +
'-outputfilepath \ "' + transform.out+ '\" ';
+ '\" ' is missing in your command.
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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