Home > Software design >  XSLT: splitting xml file based on attribute
XSLT: splitting xml file based on attribute

Time:10-30

I have an xml file containing of participants in courses A and B. All participants are in groups. Group 03 has followed a course Level A.

<contacts>
   <contact>
      <informalname>Jan</informalname>
      <formalname>met de Pet</formalname>
      <cursus level="LevelA" group="03">
         <coursetown>Amsterdam</coursetown>
         <coursedate>4 and 11 March 2021</coursedate>
         <coursename>Fantastic Course A</coursename>
      </cursus>
      <cursus level="LevelB" group="05">
         <coursetown>Rotterdam</coursetown>
         <coursedate>15 and 22 november 2021</coursedate>
         <coursename>Fantastic Course Level B</coursename>
      </cursus>
   </contact>

   <contact>
      <informalname>Maria</informalname>
      <formalname>Zusenzo</formalname>
      <cursus level="LevelA" group="01">
         <coursetown>Amsterdam</coursetown>
         <coursedate>2 and 16 november 2020</coursedate>
         <coursename>Fantastic Course A</coursename>
      </cursus>
      <cursus level="LevelB" group="05">
         <coursetown>Rotterdam</coursetown>
         <coursedate>15 and 22 november 2021</coursedate>
         <coursename>Fantastic Course Level B</coursename>
      </cursus>
   </contact>
</contacts>

I can split the xml file in subfiles, with which I can produce attendance lists and certificates. But the result still contains information on other groups the participant was in.

My intention is to split the xml file in separate files on group number, which contain the information on the participant, and only data pertaining to the cursus / course of that particular group.

In the case of group "05", the desired output is as follows:

<contacts>
   <contact>
      <informalname>Jan</informalname>
      <formalname>met de Pet</formalname>
      <cursus level="LevelB" group="05">
         <coursetown>Rotterdam</coursetown>
         <coursedate>15 and 22 november 2021</coursedate>
         <coursename>Fantastic Course Level B</coursename>
      </cursus>
   </contact>

   <contact>
      <informalname>Maria</informalname>
      <formalname>Zusenzo</formalname>
      <cursus level="LevelB" group="05">
         <coursetown>Rotterdam</coursetown>
         <coursedate>15 and 22 november 2021</coursedate>
         <coursename>Fantastic Course Level B</coursename>
      </cursus>
   </contact>
</contacts>

I now use the following xslt file:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>

  <xsl:template match="contacts">
  <xsl:for-each-group select="contact" group-by="cursus/@group">
    <xsl:result-document href="groep-{current-grouping-key()}.xml">
       <contacts>
<xsl:apply-templates select="current-group()"/>
       </contacts>
    </xsl:result-document>
  </xsl:for-each-group>
</xsl:template>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

I tried to add a second template with statements like <xsl:if test="@group = current-grouping-key()"/>, but they give no result. I hope you can help me out. Thank you in advance.

CodePudding user response:

Add

<xsl:template match="contact/cursus">
   <xsl:if test="@group = current-grouping-key()">
     <xsl:next-match/>
   </xsl:if>
</xsl:template>

to copy only matching cursus elements.

  • Related