Remix.run Logo
Kuyawa a day ago

20 years ago I saw the greatness of xml and xslt as I was coming from the painful inferno of an EDI shop. There is nothing more beautiful than sending plain data to a client and being able to see the whole document without any extra bloating, that's what XSLT was intended for:

  <?xml version="1.0"?>
  <?xml-stylesheet type="text/xsl" href="/invoice.xsl"?>
  <invoice>
    <date>2025-08-23</date>
    <customer>
      <name>John Doe</name>
      <address>
        <line>123 Sunny Boulevard</line>
        <city>Miami</city>
        <state>FL</state>
        <zip>33133</zip>
      </address>
    </customer>
    <items>
      <item>
        <code>123456</code>
        <description>Some Apple gadget</description>
        <quantity>1</quantity>
        <price>1234.56</price>
        <total>1234.56</total>
      </item>
      <item>more items...</item>
    </items>
  </invoice>
That piece of data would be sent to millions of customers and they could open it and the XML was transformed in an invoice perfectly formatted for human consumption. Both flesh and silicon were living happy in perfect harmony.

Then it came SOAP and all the corporate suits and messed it all up into an extra complicated bloatness of anguish and suffering, but XML/XSLT were beautiful on their own (for data transformation, not web pages)

Kuyawa a day ago | parent [-]

If we extrapolate it all to JSON, all we need to do is add two lines to the data file to reference the JSLT source and then use any templating system as default (ejs, mustache, handlebars) to do the transformation in the browser

  {
    "JSLT": "1.0",
    "style": "/invoice.jsl",
    "data": {
      "invoice":{
        "date": "2025-08-23",
        "customer": {
          "name": "John Doe",
          "address": {
            "line": "123 Sunny Boulevard",
            "city": "Miami",
            "state": "FL",
            "zip": "33133",
          },
        },
        "items": [
          {
            "code": "123456",
            "description": "Some Apple gadget",
            "quantity": "1",
            "price": "1234.56",
            "total": "1234.56",
          },
          {
            "code": "123457",
            "description": "Another Apple gadget",
            "quantity": "1",
            "price": "1234.57",
            "total": "1234.57",
          }
        ]
      }
    }
  }
Then the JSLT file:

  <html>
  <body>
    <h2>Invoice</h2>
    <p><label>Date</label> <span><%=data.invoice.date%></span></p>
    <div>
      <h3>Customer</h3>
      <p><%=data.invoice.customer.name%></p>
      <p>
        <%=data.invoice.customer.address.line%>
        <%=data.invoice.customer.address.city%>
        <%=data.invoice.customer.address.state%>
        <%=data.invoice.customer.address.zip%>
      </p>
    </div>
    <table>
      <tr>
        <th>Code</th>
        <th>Description</th>
        <th>Quantity</th>
        <th>Price</th>
        <th>Total</th>
      </tr>
      <% for(item of invoice.items) { %>
        <tr>
          <td><%=item.code%></td>
          <td><%=item.description%></td>
          <td><%=item.quantity%></td>
          <td><%=item.price%></td>
          <td><%=item.total%></td>
        </tr>
      <% } %>
    </table>
  </body>
  </html>
Then we could get rid of XSLT