XML : XSLT Create a nested structure from a flat structure by using certain level criteria

I want to create a XSD structure from an Excel output using XSLT. But my XSLT does not generate the structure, correctly. The Excel XML output looks like following:

  <?xml version="1.0" encoding="UTF-8" standalone="yes"?>  <nodes>      <node typeTag="Test" nodeTag="GGG" minOccurs="0" segmentMaxOccurs="1" groupMaxOccurs="1000000">          <metaInfo><ID>40</ID><Level>1</Level></metaInfo>      </node>      <node typeTag="Test" nodeTag="BBB" minOccurs="0" segmentMaxOccurs="1" groupMaxOccurs="1000000">          <metaInfo><ID>60</ID><Level>2</Level></metaInfo>      </node>      <node typeTag="Test" nodeTag="XXX" minOccurs="0" segmentMaxOccurs="1000000" groupMaxOccurs="">          <metaInfo><ID>80</ID><Level>2</Level></metaInfo>      </node>      <node typeTag="Test" nodeTag="AAA" minOccurs="0" segmentMaxOccurs="1" groupMaxOccurs="1000000">          <metaInfo><ID>90</ID><Level>1</Level></metaInfo>      </node>      <node typeTag="Test" nodeTag="WWW" minOccurs="0" segmentMaxOccurs="1" groupMaxOccurs="1000000">          <metaInfo><ID>110</ID><Level>1</Level></metaInfo>      </node>      <node typeTag="Test" nodeTag="OOO" minOccurs="0" segmentMaxOccurs="1" groupMaxOccurs="1000000">          <metaInfo><ID>130</ID><Level>1</Level></metaInfo>      </node>      <node typeTag="Test" nodeTag="AAA" minOccurs="0" segmentMaxOccurs="1" groupMaxOccurs="1000000">          <metaInfo><ID>140</ID><Level>2</Level></metaInfo>      </node>      <node typeTag="Test" nodeTag="WWW" minOccurs="0" segmentMaxOccurs="1" groupMaxOccurs="1000000">          <metaInfo><ID>160</ID><Level>2</Level></metaInfo>      </node>  </nodes>    

Each node should be an element, whereby segmentMaxOccurs != 0 will generate to leaf element and groupMaxOccurs will generate group elements. The Level defines the hierarchy of the structure (it should be a nested structure) and the id is an absolute ordered unique identifier. Base on this input, I would like to get the following XSD structure:

  Test     GGG        (ID='40')        GGG     (ID='40')        BBB     (ID='60')           BBB  (ID='60')            XXX  (ID='80')     AAA        (ID='90')        AAA     (ID='90')     WWW        (ID='100')        WWW     (ID='100')     OOO        (ID='130')        OOO     (ID='130')        AAA     (ID='140')           AAA  (ID='140')        WWW     (ID='160')           WWW  (ID='160')    

But I just get the following output:

  Test     GGG        (ID='40')        GGG     (ID='40')        BBB     (ID='60')           BBB  (ID='60')            XXX  (ID='80')        AAA     (ID='140')           AAA  (ID='140')        WWW     (ID='160')           WWW  (ID='160')     AAA        (ID='90')        AAA     (ID='90')     WWW        (ID='100')        WWW     (ID='100')     OOO        (ID='130')        OOO     (ID='130')        AAA     (ID='140')           AAA  (ID='140')        WWW     (ID='160')           WWW  (ID='160')    

The group "GGG" has the two addtional groups AAA (ID = 140) and WWW (ID = 160), which should be just underneath the group OOO. Do you have any idea, how just the correct nodes of GGG will be processed until the group AAA (ID = 90), which is at the same level like group "GGG".

This is my most relevant XSLT snippet:

  <xsl:template match="node">          <xsl:element name="xs:complexType">              <xsl:element name="xs:sequence">                  <xsl:variable name="vLevel" select="0"/>                  <xsl:variable name="vNextLevel" select="1"/>                  <xsl:variable name="vGroupCounter" select="count($vMessageTypeStructure/nodes/node[@typeTag = $vRootNode and @groupMaxOccurs != ''])"/>                  <xsl:apply-templates select="$vMessageTypeStructure/nodes/node[@typeTag = $vRootNode and ((@groupMaxOccurs != '' and ./metaInfo/Level = $vNextLevel) or (@groupMaxOccurs = '' and ./metaInfo/Level = $vLevel))]" mode="MessageStructure">                      <xsl:with-param name="pRootNode" select="$vRootNode"/>                      <xsl:with-param name="pLevel" select="$vLevel"/>                      <xsl:with-param name="pGroupCounter" select="$vGroupCounter"/>                  </xsl:apply-templates>              </xsl:element>          </xsl:element>      </xsl:element>  </xsl:template>  <!-- ################################ -->  <!-- Call Template: Create Sub Structure  / Leaf Nodes -->  <!-- ################################ -->  <xsl:template match="node[@groupMaxOccurs = '']" mode="MessageStructure">      <xsl:param name="pRootNode"/>      <xsl:param name="pLevel"/>      <xsl:param name="pGroupCounter"/>      <xsl:variable name="vActGroupCounter" select="count(following-sibling::node[@typeTag = $pRootNode and @groupMaxOccurs != ''])"/>      <xsl:if test="./metaInfo/Level = $pLevel and ($vActGroupCounter = $pGroupCounter or $pLevel = 0)">          <xsl:element name="xs:element">              <xsl:attribute name="name" select="@nodeTag"/>              <xsl:attribute name="minOccurs" select="@minOccurs"/>              <xsl:attribute name="maxOccurs" select="functx:max-occurs(@segmentMaxOccurs)"/>          </xsl:element>      </xsl:if>  </xsl:template>  <!-- ################################ -->  <!-- Call Template: Create Sub Structure  / Group Nodes -->  <!-- ################################ -->  <xsl:template match="node[@groupMaxOccurs != '']" mode="MessageStructure">      <xsl:param name="pRootNode"/>      <xsl:param name="pLevel"/>      <xsl:param name="pGroupCounter"/>      <xsl:variable name="vNextLevel" select="$pLevel + 1"/>      <xsl:variable name="vActGroupCounter" select="count(following-sibling::node[@typeTag = $pRootNode and @groupMaxOccurs != ''])"/>      <xsl:variable name="vNextGroupLevel" select="following-sibling::node[@typeTag = $pRootNode and @groupMaxOccurs != ''][1]/metaInfo/Level"/>      <xsl:element name="xs:element">          <xsl:attribute name="name" select="functx:replace-first(@nodeTag, 'S', 'G')"/>          <xsl:attribute name="minOccurs" select="@minOccurs"/>          <xsl:attribute name="maxOccurs" select="functx:max-occurs(@groupMaxOccurs)"/>          <xsl:element name="xs:complexType">              <xsl:element name="xs:sequence">                  <xsl:element name="xs:element">                      <xsl:attribute name="name" select="@nodeTag"/>                      <xsl:attribute name="minOccurs" select="@minOccurs"/>                      <xsl:attribute name="maxOccurs" select="functx:max-occurs(@segmentMaxOccurs)"/>                  </xsl:element>                  <xsl:apply-templates select="following-sibling::node[@typeTag = $pRootNode and ((@groupMaxOccurs != '' and ./metaInfo/Level = $vNextLevel + 1 and ./metaInfo/Level = $vNextGroupLevel) or (@groupMaxOccurs = '' and ./metaInfo/Level = $vNextLevel))]" mode="MessageStructure">                      <xsl:with-param name="pRootNode" select="$pRootNode"/>                      <xsl:with-param name="pLevel" select="$vNextLevel"/>                      <xsl:with-param name="pGroupCounter" select="$vActGroupCounter"/>                  </xsl:apply-templates>              </xsl:element>          </xsl:element>      </xsl:element>  </xsl:template>    

Any support is really appreciated. Many thanks in advance.

No comments:

Post a Comment