javascriptxmlvariablesautomationadobe-indesign

How can I populate JavaScript variables from an XML file?


I am working on an automated publishing flow that populates InDesign templates using XML data. The workflow is triggered when an XML file is added to a watch folder.

In order to identify the correct InDesign template to use, I need to pull a few key data points into the JavaScript executed by InDesign.

For example, if the element at the beginning of the XML file contains "CO" (for Colorado), I want top set a JS region variable to be "CO" and then use that variable to determine where the data is sent.

EDITED: Updated with actual XML

So if the XML looks like:

<Root xmlns="kpPDCommon" xmlns:kpdc="kpPDCommon">
    <region kpdc:regionCD="CO">CO</region>
    <lob kpdc:lobCD="MCAR">Medicare</lob>
    <serviceArea kpdc:saCD="DB">Denver Metropolitan Service Area</serviceArea>
    <saPlans>
        <planName>Senior Advantage (HMO)</planName>
        <planName>Senior Advantage Medicare Medicaid (HMO D-SNP)</planName>
        <planName>Senior Advantage (HMO-POS)</planName>
    </saPlans>
...

I want to use that to in my JS file:

var RGN = region;
var VER = version;

These variables are then used to select the appropriate InDesign template to import the XML into.

I am new to JavaScript and would appreciate as much guidance as possible.

However, please note that the script in question must be a JSX script run by Adobe InDesign. It will NOT be run in a browser. InDesign is a fully scriptable application that runs JSX scripts either on startup or on-demand when run from its scripts panel. This script will be used as a part of an automated publishing workflow within InDesign.

I reviewed the following options but have not been able to find a solution:

  1. https://bytes.com/topic/xml/answers/694987-passing-xml-element-data-javascript-asp-va , I need to populate a JS variable for InDesign and an xsl will not do what I want
  2. https://medium.com/frontendweb/how-to-read-local-json-file-in-react-js-564125235fc7 , I am working with large data files and only want to pull variable data from the beginning of the file.
  3. https://www.youtube.com/watch?v=lUCQgqc4K2A , Same as #2, also, I would need to load a LOCAL xml file.
  4. https://50linesofco.de/post/2019-07-05-reading-local-files-with-javascript, again, I am working with very large, deeply nested, data files.

I also tried the following:

import("C:/Users/O146962/OneDrive - Kaiser Permanente/Desktop/Indesign Automation POC/Data/CO_DNB_Providers_Test_BR4.xml").then(response => {
    return response.text();
}).then(xmlString => {
 const xmlDocument = new DOMParser().parseFromString(xmlString, "text/xml");
 const region = xmlDocument.querySelectorAll("region");
 for (const region of region) {
    const code = region.textContent;
 }
 console.log();
});

But so far this has not worked either, since it will not load a local file.

To be clear, I do NOT want to load or import the entire xml file! I want to pull in a couple of variables defined at the start of the document.


Solution

  • It's probably something like this:

    var folder = Folder('/Users/me/test');
    var file = File(folder + '/test.xml');
    
    file.open('r');
    var xml = new XML(file.read());
    file.close();
    
    var RGN = xml.region.text();
    var VER = xml.version.text();
    
    alert('RGN: ' + RGN + ', VER: ' + VER);
    

    Result:

    enter image description here


    Update

    Here is the proper approach:

    XML file:

    <?xml-model href="../CO-Medicare_Combined-Structure.xsd"?>
    <!DOCTYPE Root [
      <!ENTITY path "file:///C:/Users/O146962/OneDrive - Kaiser Permanente/Desktop/Indesign Automation POC/Assets/Icons/">
    ]>
    <Root xmlns="kpPDCommon" xmlns:kpdc="kpPDCommon">
      <region kpdc:regionCD="CO">CO</region>
      <lob kpdc:lobCD="MCAR">Medicare</lob>
      <serviceArea>Denver Boulder</serviceArea>
      <planName>Senior Advantage Medicare Medicaid</planName>
    </Root>
    

    Code:

    var dataPath = Folder("/Users/.../");
    var file = File(dataPath + "/test.xml");
    
    var ns = new Namespace ("kpPDCommon");
    
    file.open("r");
    var xml = new XML(file.read());
    file.close();
    
    var RGN = xml.ns::region;
    var LOB = xml.ns::lob;
    var SVCA = xml.ns::serviceArea;
    var SVCA_PN = xml.ns::planName;
    
    alert("RGN: " + RGN + ", LOB: " + LOB + ", SVCA_PN: " + SVCA_PN);
    

    Result:

    enter image description here