0

How can I use Jsonix in Google Apps Script (server side Google Docs automation)? If I can't, what's an alternate to Jsonix I can use in GAS to generate Javascript mappings from XSD, then serialize a JS object to XML for submission to a REST API, then deserialize the response back into a JS object?

I used Jsonix to compile a REST API from its XSD files to JSON mappings. I tested OK in commandline Node.js a Javascript that creates a JS object from inline JSON, then marshals it under the Jsonix.Context for submisstion to the REST API, then unmarshals the response.

Then I created a Google Apps Script project with my script. I created another GAS project with the Jsonix.js script (as Jsonix.gs), then another GAS project with the mappings script (as API.gs). I configured my main script's project Resources with the Jsonix and API libraries' project keys. I can execute my script (verifying the library resources are used), but it fails when Jsonix.createDocument() is called. I inserted into the beginning of the Jsonix library script's _jsonix_factory = function(_jsonix_xmldom, _jsonix_xmlhttprequest, _jsonix_fs) a Logger.log("_jsonix_xmldom: " + _jsonix_xmldom) line that logs _jsonix_xmldom: undefined , which is why Jsonix.createDocument() throws an error instead of returning a document.

Can I use the Google Apps Script service XmlService, or some other service in the GAS environment, instead of the _jsonix_xmldom that Jsonix expects by default? Or can I include as a library resource some functionally equivalent libraries? Or otherwise supply that functionality to Jsonix in GAS?

I expect that similar errors will result from Jsonix trying to use the _jsonix_xmlhttprequest and _jsonix_fs values that are also undefined. I see in the Jsonix.js (.gs) source code the two lines // REWORK // Node.js in the createDocument() declaration and elsewhere. Perhaps this case I'm reporting is in active development?

Thanks for your insights.

Matthew
  • 757
  • 11
  • 19
  • Note that all globals in all dependencies are evaluated for every new instance, so if your project gets sluggish that would be why. There's no persistence in Google Apps Script between server instances. – tehhowch Aug 14 '18 at 18:46

3 Answers3

0

Based on the jsonix.js source on github, it looks like you would have to undertake significant work to get it running in GAS. The XMLDOM and document objects simply do not exist within the GAS environment, you would need to modify jsonix to use the XmlService and UrlFetchApp services provided by Apps Script.

Note that while it looks like a fair bit or work, jsonix appears to be structured to handle different environments and it would by no means be impossible or even that difficult to add GAS support.

Cameron Roberts
  • 7,127
  • 1
  • 20
  • 32
  • My external Jsonix library project is accessed fine by my main GAS project's script. The Jsonix script runs. The problem is the Jsonix project's script is calling methods on the XMLDOM library that the Jsonix script's wrapper factory function is expecting to receive as an argument passed to it by its environment, but the GAS environment isn't passing it when the environment calls the factory function. It looks like I have to supply the XMLDOM library somehow. Since library resources are working for me, that approach seems the right way. But what exactly to implement as a library resource? – Matthew Aug 14 '18 at 17:44
  • Ah sorry I misunderstood the problem, I thought it was an issue of self-references within jsonix coming up undefined. I will either delete or completely rewrite this answer since it isn't relevant as is. I think your only option will be to refactor jsonix to use the relevant apps script services, maybe a big project in and of itself – Cameron Roberts Aug 14 '18 at 17:50
  • I took a quick look at the jsonix code and re-wrote this answer. – Cameron Roberts Aug 14 '18 at 19:26
0

I am the author of Jsonix.

I have no idea what "Google Apps Script" is. For sure this is not something "in active development".

Jsonix supports Node.js and browser environments OOTB. The factory function _jsonix_factory simply receives the dependencies which are expected to be provided by the environment. If dependencies are not provided, some of the features will not work.

Currently there are three dependencies:

  • xmldom
  • xmlhttprequest
  • fs

fs is completely optional. If fs is not provided, you will not be able to work with files - methods like unmarshalFile will not work. No surpize, no big deal.

xmlhttprequest is only needed if you want to parse from URLs in non-browser environment. Without it, unmarshalURL won't work (in non-browser environments).

xmldom provides DOM parser in non-browser environments. Jsonix uses DOM to parse XML, so you'll either need browser-provided DOM or provide xmldom as dependency. This is critical, Jsonix won't work at all otherwise.

So basically the only thing you really really need is xmldom. It will be used for:

  • xmldom.DOMImplementation
  • xmldom.XMLSerializer
  • xmldom.DOMParser

Is there a DOM implementation for GAS? If yes, you will quite probably be able to pass it as a dependency to _jsonix_factory. If not, sorry, can't do anything.

lexicore
  • 42,748
  • 17
  • 132
  • 221
0

I wound up creating new Google Apps Script projects for Jsonix, for its XMLDOM dependency, and for my API mappings JS (GAS) that I generated with Jsonix from the API's XSD files. I made my GAS Jsonix project depend on my XMLDOM project as a library resource. Then I made a GAS project for my main script, which depends on the Jsonix GAS project and the API GAS project as library resources. It works.

I used an existing, well tested XMLDOM project with an appropriate FOSS license, and tweaked it to fit the GAS API requirements.

I tried using the GAS XmlService, wrapping its API to present its relevant members as DOMImplementation, DOMParser and XMLSerializer, but the the XmlService API is deeply inconsistent with the XMLDOM API. The XmlService API's members corresponding to the standard DOM implementation's are structured not at all consistently with the standard API.

Matthew
  • 757
  • 11
  • 19