node.jsjsonxmlxml2js

Getting the desired xml representation of an array from a plain object using nodejs


I am using nodejs and typescript. It is necessary to get such an xml file structure from the object, in which the number of nested Rub tags is arbitrary:

    <Doc file="jdsf35aasdg">
        <Rub id="1" name="Руб1" />
        <Rub id="2" name="Руб2" />
        <Rub id="3" name="Руб3" />
    </Doc>

The structure of the original object is not important to me, only the resulting xml. The closest result I got was with this initial object:

const doc = {
    Doc : {
        $ : {
            "file" : "jdsf35aasdg"
        },
        Rub : {
            $: {
                id : "1",
                name : "Руб1"
            }
        }
    }
};

const builder = new xml2js.Builder({
    headless: true
});

return builder.buildObject(object);


<Doc file="jdsf35aasdg">
     <Rub id="1" name="Руб1"/>
</Doc>

But I could not set an array instead of one element - an error of the object structure. How do I need to set an object in order to get the result shown above as a result of the conversion to xml?

Thanks in advance!


Solution

  • If you want to construct XML then XSLT is a good choice, in Node.js and in client-side JavaScript you have XSLT 3.0 and XPath 3.1 support thanks to Saxon-JS (https://www.npmjs.com/package/saxon-js), so your example used in Node.js would look like

    const SaxonJS  = require("saxon-js");
    
    var myObjects = [{ id : 1, name : 'Руб1' }, {id : 2, name : 'Руб2'}, { id : 3, name : 'Руб3'}];
    
    var myFile = 'jdsf35aasdg';
    
    const xslt = `<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all">
    
      <xsl:param name="file" as="xs:string"/>
      <xsl:param name="rubs" as="map(*)*"/>
      
      <xsl:output indent="yes"/>
      
      <xsl:template name="xsl:initial-template">
        <Doc file="{$file}">
          <xsl:iterate select="$rubs">
            <Rub id="{?id}" name="{?name}"/>
          </xsl:iterate>
        </Doc>
      </xsl:template>
    </xsl:stylesheet>`;
    
    const result = SaxonJS.XPath.evaluate(`
      transform(
        map {
          'stylesheet-text' : $xslt,
          'delivery-format' : 'serialized',
          'stylesheet-params' : map {
            QName('', 'file') : $file,
            QName('', 'rubs') : $rubs
          }
        }
      )?output
    `, [], {
      params : {
        xslt : xslt,
        file : myFile,
        rubs : myObjects
        }
        });
        
    console.log(result);
    

    and output e.g.

    <?xml version="1.0" encoding="UTF-8"?>
    <Doc file="jdsf35aasdg">
       <Rub id="1" name="Руб1"/>
       <Rub id="2" name="Руб2"/>
       <Rub id="3" name="Руб3"/>
    </Doc>
    

    You can also run it in the browser:

    var myObjects = [{ id : 1, name : 'Руб1' }, {id : 2, name : 'Руб2'}, { id : 3, name : 'Руб3'}];
    
    var myFile = 'jdsf35aasdg';
    
    const xslt = `<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all">
    
      <xsl:param name="file" as="xs:string"/>
      <xsl:param name="rubs" as="map(*)*"/>
      
      <xsl:output indent="yes"/>
      
      <xsl:template name="xsl:initial-template">
        <Doc file="{$file}">
          <xsl:iterate select="$rubs">
            <Rub id="{?id}" name="{?name}"/>
          </xsl:iterate>
        </Doc>
      </xsl:template>
    </xsl:stylesheet>`;
    
    const result = SaxonJS.XPath.evaluate(`
      transform(
        map {
          'stylesheet-text' : $xslt,
          'delivery-format' : 'serialized',
          'stylesheet-params' : map {
            QName('', 'file') : $file,
            QName('', 'rubs') : $rubs
          }
        }
      )?output
    `, 
     [], 
     {
      params : {
        xslt : xslt,
        file : myFile,
        rubs : myObjects
      }
     }
    );
        
    console.log(result);
        
    <script src="https://martin-honnen.github.io/Saxon-JS-2.4/SaxonJS2.js"></script>