solidden
solidden

Reputation: 11

XSL from XML to split the file

I have a below xml sample file, with huge records. I would like to split this into two failedItems based on header/testbook-id. The resulting file should have price-tables/price-table/@product-id and price-tables/price-table/amount

I am facing challenges to spit the file and select columns i need. Any help would be great help.

<?xml version="1.0" encoding="UTF-8"?>
<testbooks xmlns="http://www.demandware.com/xml/impex/testbook/2006-10-31">
  <testbook>
    <header testbook-id="ca-cad-list">
      <currency>CAD</currency>
      <online-flag>true</online-flag>
    </header>
    <price-tables>
      <price-table product-id="035:M:1:">
        <online-from>2022-06-02T00:00:00.000Z</online-from>
        <online-to>9999-12-31T23:59:59.000Z</online-to>
        <amount quantity="1">90.00 </amount>
      </price-table>
    </price-tables>
  </testbook>

  <testbook>
    <header testbook-id="ca-cad-sale">
      <currency>CAD</currency>
      <online-flag>true</online-flag>
    </header>
    <price-tables>
      <price-table product-id="035:M:1:">
        <online-from>2022-06-02T00:00:00.000Z</online-from>
        <online-to>9999-12-31T23:59:59.000Z</online-to>
        <amount quantity="1">85</amount>
      </price-table>
    </price-tables>
  </testbook>
  
</testbooks>

Upvotes: 0

Views: 50

Answers (1)

Martin Honnen
Martin Honnen

Reputation: 167716

In XSLT 3 you can use grouping and then xsl:result-document, obviously, plus empty templates to avoid copying data you don't want in the output e.g.

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="3.0"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xpath-default-namespace="http://www.demandware.com/xml/impex/testbook/2006-10-31"
  exclude-result-prefixes="#all"
  expand-text="yes">
  
  <xsl:template match="testbooks">
    <xsl:for-each-group select="testbook" group-by="header/@testbook-id">
      <xsl:result-document href="{current-grouping-key()}.xml">
        <xsl:copy select="..">
          <xsl:apply-templates select="current-group()"/>
        </xsl:copy>
      </xsl:result-document>
    </xsl:for-each-group>
  </xsl:template>
  
  <xsl:template match="price-table/online-from | price-table/online-to"/>

  <xsl:strip-space elements="*"/>
  <xsl:output indent="yes"/>
  
  <xsl:mode on-no-match="shallow-copy"/>
  
</xsl:stylesheet>

That assumes you just want to split based on the header/@testbook-id but preserve the testbook elements. The grouping would of course also allow you to join/merge the elements belonging to a group.

Upvotes: 1

Related Questions