0

Suppose I have a XML like:

<A>
<B n='key1' v='value1'/>
<B n='key2' v='value2'/>
<B n='key3' v='value3'/>
<B n='key4' v='value4'/>
</A>

Note: This is only 4 rows what I have provided but it is having so many rows (B tag).

I want to transform it into :

<XYZ name='value1'>
<MNP>value2</MNP>
</XYZ>
<XYZ name='value3'>
<MNP>value4</MNP>
</XYZ>

I need to do in azure apim.

Rishav Raj
  • 93
  • 5
  • How do you know which B nodes are transformed into an XYZ node and which ones into an MNP subnode? – Pierre François Jul 13 '21 at 12:48
  • @PierreFrançois Just assume value1 ,value 3 and then value10 -> xyz Values b/w value 1 and value3 , values b/w value 3 and value10 and values b/w value 10 till end - > MNP – Rishav Raj Jul 13 '21 at 12:51
  • 1
    Your desired output XML is not well-formed. – Yitzhak Khabinsky Jul 13 '21 at 12:51
  • I still not understand how your code can know that only B nodes containing value1, value3 and value10 must undergo a different processing. Is there some variable containing the sequence value1, value3 and value10? Please edit your question to complete it. Martin Honnen (below) supposed that only the B nodes at an uneven position have to be turned into an XYZ node. – Pierre François Jul 13 '21 at 19:43
  • Once we get the values like value1,3 and 10 it will go to XYZ tag. This is kind of checking the value, if value is value1 or 3 or 10 then it will go to XYZ otherwise in MNP tag. – Rishav Raj Jul 14 '21 at 06:45
  • *Where* do you "get the values like value1,3 and 10"? In an external variable? Has it to be hard coded? Try to understand my questions, please. – Pierre François Jul 14 '21 at 09:22
  • Yes it is hard coded – Rishav Raj Jul 14 '21 at 12:49

1 Answers1

0

With positional grouping in XSLT 2 or 3 you can solve it with

<?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"
  exclude-result-prefixes="#all"
  expand-text="yes">

  <xsl:output method="xml" indent="yes"/>
  
  <xsl:template match="A">
    <xsl:copy>
      <xsl:for-each-group select="B" group-adjacent="(position() - 1) idiv 2">
        <XYZ name="{@v}">
          <MPN>{current-group()[2]/@v}</MPN>
        </XYZ>
      </xsl:for-each-group>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

With XSLT 1 you can process B[position() mod 2 = 1] to create the XYZ element and then navigate to following-sibling::B[1] to create the MPN element:

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

  <xsl:output method="xml" indent="yes"/>
  
  <xsl:template match="A">
    <xsl:copy>
      <xsl:for-each select="B[position() mod 2 = 1]">
        <XYZ name="{@v}">
          <MPN>
            <xsl:value-of select="following-sibling::B[1]/@v"/>
          </MPN>
        </XYZ>
      </xsl:for-each>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>
Martin Honnen
  • 160,499
  • 6
  • 90
  • 110