-1

I need to transform an XML structure to another XML structure by grouping nearby elements using XSLT version 1 and store into a variable for later process.

My current solution: https://xsltfiddle.liberty-development.net/naZXVF1/3

XML

<?xml version="1.0"?>
 <Items>
      <Parameter>1</Parameter>
      <Parameter>2</Parameter>
      <Menu>1</Menu>
      <Parameter>3</Parameter>
      <Parameter>4</Parameter>
      <Menu>2</Menu>
      <Menu>3</Menu>
      <Parameter>5</Parameter>
      <Parameter>6</Parameter>
      <Parameter>7</Parameter>
      <Parameter>8</Parameter>
  </Items>

Expected Result

<Items>
   <Parameters>
      <Parameter>1</Parameter>
      <Parameter>2</Parameter>
   </Parameters>
   <Menus>
     <Menu>1</Menu>
   </Menus>  
   ...
</Items>
user1219310
  • 732
  • 1
  • 9
  • 23
  • You have used Saxon 9.8 as the XSLT processor in the fiddle, it is an XSLT 3 processor. In your XSLT code you have used `version="2.0"`. So why is the question tagged as XSLT 1.0? – Martin Honnen Apr 24 '20 at 09:12
  • sorry for the confusion, I have updated to version="1.0" – user1219310 Apr 24 '20 at 09:16
  • 1
    Answers are no longer allowed, so i leave a comment: [https://xsltfiddle.liberty-development.net/gVhDDyX](https://xsltfiddle.liberty-development.net/gVhDDyX). It is XSLT 1.0. –  Apr 25 '20 at 18:48
  • @mark61, thanks for your reply and time! your answer definitely helped me a lot to think and create a solution for the existing project. Good day to you and stay safe! – user1219310 Apr 27 '20 at 01:07

1 Answers1

1

Either use sibling recursion or use a complicated key to identify the elements belonging together:

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

  <xsl:output indent="yes"/>

  <xsl:key name="group" match="*[name(preceding-sibling::*[1]) = name()]"
    use="generate-id(preceding-sibling::*[name() = name(current())][name(preceding-sibling::*[1]) != name()][1])"/>

  <xsl:template match="Items">
      <xsl:copy>
          <xsl:apply-templates select="*[name(preceding-sibling::*[1]) != name()]"/>
      </xsl:copy>
  </xsl:template>

  <xsl:template match="Items/*">
      <xsl:element name="{name()}s">
          <xsl:copy-of
            select=". | key('group', generate-id())"/>
      </xsl:element>
  </xsl:template>
</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/naZXVF1/4

Martin Honnen
  • 160,499
  • 6
  • 90
  • 110
  • 1
    Solution with no recursion or (complicated) key: [https://xsltfiddle.liberty-development.net/6pS26mP](https://xsltfiddle.liberty-development.net/6pS26mP) :). PS: Why is the post closed? ... –  Apr 25 '20 at 07:32