node.jsjsonxmlbuild

How to generate xml doc from json object with nested array?


I am trying to generate xml doc from js object in env node.js. My js object likes:

{
    "root": {
        "id": 12,
        "title": "root title",
        "people": [
            {"id": 33,"name": "Bill"},
            {"id": 34,"name": "Elon"}
        ],
        "camps":[
            {"id":1,"addr":"in mountain"},
            {"id":2,"addr":"t lake"}
        ]
    }
}

the expected xml is:

<?xml version="1.0" encoding="UTF-8"?>
<root id="12" title="root title">
    <people>
        <person id="33" name="Bill" />
        <person id="34" name="Elon" />
    </people>
    <camps>
        <camp id="1" addr="in mountain"/>
        <camp id="2" addr="at lake"/>
    </camps>
</root>

I have tried some libs, their result likes below. They all split array into multiple elements with excessive wrapping. That leads to losing the hierachical relations and the result looks illogical.

<?xml version="1.0"?>
<root>
  <id>12</id>
  <title>root title</title>
  <people>
    <id>33</id>
    <name>Bill</name>
  </people>
  <people>
    <id>34</id>
    <name>Elon</name>
  </people>
  <camps>
    <id>1</id>
    <addr>In mountant</addr>
  </camps>
  <camps>
    <id>1</id>
    <addr>At lake</addr>
  </camps>
</root>

Solution

  • No off-the-shelf json-to-xml converter (or xml-to-json for that matter) will ever produce exactly the xml that you want.

    Try XSLT 3.0:

    <xsl:variable name="json" select="json-doc('input.json')"/>
    <root id="{$json?root?id}" title="{$json?root?title}">
      <people>
         <xsl:for-each select="$json?root?people?*">
           <person id="{?id}" name="{?name}"/>
         </xsl:for-each>
      </people>
      <camps>
         <xsl:for-each select="$json?root?camps?*">
           <camps id="{?id}" addr="{?addr}"/>
         </xsl:for-each>
      </camps>
    </root>
    

    XSLT 3.0 is available in node.js via [disclaimer: my company's product] SaxonJS.

    XQuery 3.0 would be another possibility.