7 Replies Latest reply on Apr 22, 2016 12:51 AM by rajrev14364

    How do I load an XML file, and save it as an fm file

    rajrev14364

      Hi Experts,

       

      I have a bunch of XML files in a folder. What I'd like to achieve is that, I'd like to iteratively load the xml using a StructuredApplication and save it as an FM file. I've been able to sucessfully load the XML file but I'm having difficulty in saving it as an FM file.

       

      Here is the code that I've written so far:

       

      if (sourceFolder != null){ // If a valid folder is selected

          files = new Array(); 

          fileType = "*.xml"; 

          files = sourceFolder.getFiles(fileType);  // Get all files matching the pattern 

          if (files.length > 0) { // Get the destination to save the files 

              destFolder = Folder.selectDialog( 'Select the folder where you want to save the converted XML files.', '~' );

              for (var i = 0; i < files.length; i++) { 

                  // Set the options for opening the XML file.

                  var openParams = GetOpenDefaultParams();

                  var j = GetPropIndex(openParams, Constants.FS_OpenAsType);

                  openParams[j].propVal.ival = Constants.FV_TYPE_XML;

                  j = GetPropIndex(openParams, Constants.FS_StructuredOpenApplication);

                  openParams[j].propVal.sval = "XML snpsbook";

                  j = GetPropIndex(openParams, Constants.FS_FileIsOldVersion);

                  openParams[j].propVal.ival = Constants.FV_DoOK;

                  j = GetPropIndex(openParams, Constants.FS_FontNotFoundInDoc);

                  openParams[j].propVal.ival = Constants.FV_DoOK;

                  j = GetPropIndex(openParams, Constants.FS_FileIsInUse);

                  openParams[j].propVal.ival = Constants.FV_DoCancel;

                  j = GetPropIndex(openParams, Constants.FS_AlertUserAboutFailure);

                  openParams[j].propVal.ival = Constants.FV_DoCancel;

                  var  returnParams = new PropVals();

       

                 // I'M NOT ABLE TO GET THIS LINE TO EXECUTE. sourceDoc RETURNS AN INVALID OBJECT REFERENCE.

                  sourceDoc = Open(files[i].name, openParams, returnParams);  // Return the document object

                  alert(sourceDoc.name);

       

                  // Function to save .XML file to .FM extension

                  var saveParams = GetSaveDefaultParams();

                  var returnParamsp = new PropVals();

                  // Replace the .xml extension with .fm

                  var k = GetPropIndex(saveParams, Constants.FS_FileType);

                  saveParams[k].propVal.ival = Constants.FV_SaveFmtBinary;

                  saveAsName = sourceDoc.name.replace (/\.[^\.\\]+$/,".fm");

                  var saveInFile = Save(saveAsName, saveParams, returnParamsp);  // Save as .fm file

                  saveInFile = new File ( destFolder + '/' + targetFile);

                  saveInFile.close();  // Close file

              }

              alert('Files are saved as FM in ' + destFolder); 

          } else { 

              alert('No matching files found!!!'); 

          } 

      }

        • 1. Re: How do I load an XML file, and save it as an fm file
          frameexpert Level 4

          I am too busy right now to help you with your code, but I will give you some general principles to make it easier for you. You should really separate your tasks so you can test and troubleshoot each one individually. You basically have this for tasks:

           

          1. Prompt for a folder. This one should be easy.

          2. Get all of the XML files in the folder and look through them. You can test this by just writing the names to the JavaScript Console with $.writeln (files[i]).

          3. For each XML file, call a function that opens the file in FrameMaker. If the file is opened successfully, pass the document object to another function to save it as FrameMaker binary in the appropriate folder.

           

          So you need a function to open an xml file, given its absolute path and possibly its structured application name:

           

          function openXmlFile (filePath, structApp) {

           

            // If it successfully opens the file, return the Doc object.

          }

           

          You can test and develop this function by passing it a hard-coded path to an XML file. It is easier to test a function using a single file instead of testing it a loop like you are doing. You could then call it like this:

           

          doc = openXmlFile (files[i], "appName");

          if (doc !== undefined) {

              // Call the function to save it as FM binary.

          }

           

          Then you need a function to take a document object and save it as FrameMaker binary:

           

          function saveDoc (doc, savePath) {

           

          }

           

          Your calling code inside the files loop would then look something like this:

           

          doc = openXmlFile (files[i], "appName");

          if (doc !== undefined) {

              // Call the function to save it as FM binary.

              saveDoc (doc, savePath);

          }

           

          You could test it by opening an XML file manually in FrameMaker and seeing if your function will successfully save it. Once your functions are developed and tested, you can put everything together to work on all of the files in a folder. The way your code is currently all in one long script makes it difficult to test and troubleshoot.

           

          The other benefit of functions is that you will be able to reuse them in other scripts. I hope this helps. -Rick

          • 2. Re: How do I load an XML file, and save it as an fm file
            rajrev14364 Level 1

            Hi Rick,

             

            Thank you so very much for your guidance.

             

            I've updated my codes to reflect all the suggestions that you made. However, I'm not able to save the XML file to a FM file. I wonder where I've gone wrong.

            ------------------------------------------------------------------------------------------ ---------------------

            var sourceDoc = openXmlFile("C:\Users\rajrev\file.xml","XML snpsbook");
            if (sourceDoc !== "undefined") {
                saveToFm(sourceDoc, "C:\Users\rajrev\transformed_files\");
                sourceDoc.close();
            }

            // Function to open and XML file
            function openXmlFile(filePath, structApp) {
                var openParams = GetOpenDefaultParams();
                var i = GetPropIndex(openParams, Constants.FS_OpenAsType);
                openParams[i].propVal.ival = Constants.FV_TYPE_XML;
                i = GetPropIndex(openParams, Constants.FS_StructuredOpenApplication);
                openParams[i].propVal.sval = structApp;
                var  returnParams = new PropVals();
                Open(filePath, openParams, returnParams);
            }

            //Function to save the opened XML as an FM file
            function saveToFm(fileObject, savePath) {
                var saveParams = GetSaveDefaultParams();
                var i = GetPropIndex(saveParams, Constants.FS_FileType);
                saveParams[i].propVal.ival = Constants.FV_SaveFmtBinary;
                var saveAsName = fileObject.name.replace (/\.[^\.\\]+$/,".fm");
                var returnParamsp = new PropVals();
                Save(fileObject, saveAsName, saveParams, returnParamsp);
            }

            ------------------------------------------------------------------------------------------ -------------------------

            Thanks a lot for your time.

            Best wishes,

            Raj

            • 3. Re: How do I load an XML file, and save it as an fm file
              frameexpert Level 4

              Raj, It should be:

               

              fileObject.Save (saveAsName, saveParams, returnParamsp);

               

              Try this and see if it works.

               

              -Rick

              • 4. Re: How do I load an XML file, and save it as an fm file
                Russ Ward Level 4

                Hi Raj,

                 

                You are very close, but there are some critical flaws in your code that will prevent proper operation:

                 

                - Your paths in string literals need to have escape sequences for the backslashes. A backslash character is considered a prefix to an escape sequence, so those need to be escaped themselves. For example:  "C:\\Users\\rajrev\\file.xml".

                 

                - Your openXmlFile() function doesn't return anything, so the original sourceDoc variable never gets set.

                 

                - It is better to use the ObjectValid() method to test for a valid FM object.

                 

                - I'm no regular expression expert, but I can't figure out the logic in your replace() method at all, for creating the new file path. Furthermore, the "name" property of the fileObject is incorrect, it must be "Name". I think there are simpler ways to do this.

                 

                - Your call to the Save() method is incorrect. It should be fileObject.Save(saveAsName, saveParams, returnParamsp).

                 

                All that said, here is a quick, uncommented revision that works for me:

                 

                 

                var sourceDoc = openXmlFile("C:\\Users\\rajrev\\file.xml","XML snpsbook");
                if (sourceDoc.ObjectValid()) {
                    
                    var path = sourceDoc.Name;
                    var filename = path.substring((path.lastIndexOf("\\") + 1), path.length);
                    filename = filename.replace(".xml", ".fm");
                    
                    path = path.substring(0, (path.lastIndexOf("\\") + 1));
                    path = path + "transformed_files\\" + filename;
                    
                    //path testing
                    //alert(path);
                    
                    saveToFm(sourceDoc, path);
                    sourceDoc.Close(0);
                }
                
                // Function to open and XML file
                function openXmlFile(filePath, structApp) {
                    var openParams = GetOpenDefaultParams();
                    var i = GetPropIndex(openParams, Constants.FS_OpenAsType);
                    openParams[i].propVal.ival = Constants.FV_TYPE_XML;
                    i = GetPropIndex(openParams, Constants.FS_StructuredOpenApplication);
                    openParams[i].propVal.sval = structApp;
                    var  returnParams = new PropVals();
                    var doc = Open(filePath, openParams, returnParams);
                    return doc;
                }
                
                //Function to save the opened XML as an FM file
                function saveToFm(fileObject, savePath) {
                    var saveParams = GetSaveDefaultParams();
                    var i = GetPropIndex(saveParams, Constants.FS_FileType);
                    saveParams[i].propVal.ival = Constants.FV_SaveFmtBinary;
                    var saveAsName = savePath;
                    var returnParamsp = new PropVals();
                    fileObject.Save(saveAsName, saveParams, returnParamsp);
                }
                
                
                • 5. Re: How do I load an XML file, and save it as an fm file
                  rajrev14364 Level 1

                  Hi Russ,

                   

                  Thank you very much for the usefull and important pointers.

                   

                  I got the script to work after I made the changes that you suggested in you sample code. However, I've noticed that

                  file.fm

                  does not get physically created and dumped in the

                  transformed_files/

                  folder as per the sample script you provided.

                   

                  What do you thing might be going wrong?

                   

                  Thanks,

                  Raj

                  • 6. Re: How do I load an XML file, and save it as an fm file
                    Russ Ward Level 4

                    Raj, I don't know, it worked fine for me. Maybe uncomment the alert(path); line so you can see the exact path being generated. Does the transformed_files directory already exist? This script will not create it. A script could, but this one is not set up to do it.

                     

                    How can you say that it "worked" when it did not complete the primary objective?

                     

                    Russ

                    • 7. Re: How do I load an XML file, and save it as an fm file
                      rajrev14364 Level 1

                      Hi Russ,

                       

                      You are right. The transformed_files directory already exists and because of the following line of code the files were not getting dumped:

                           path = path + "transformed_files\\" + filename;

                       

                      Because the path variable before the above assignment already had the value c:/users/rajrev/transformed_files/. Therefore, I tweaked this line of code as follows and it worked:

                           path = path + filename;

                       

                      Earlier, I confirmed that the script "Worked" because the script did not halt the execution and went thru but did not dump the files as it could not find c:/users/rajrev/transformed_files/transformed_files/ folder as mentioned above.

                       

                      Hope I answered your question. And thanks a lot for your assitance. I was banging my head for this solution for a long time.

                       

                      Thanks again!

                      Raj

                      1 person found this helpful