0

Hi,

I have a requirement in XSLT where in I have a xml as below,

<Process>
    <name></name>
    <duration></duration>
    <time></time>
    <name></name>
    <duration></duration>
    <time></time>
    <name></name>
    <duration></duration>
    <time></time>
    .
    .
    .
    .
</Process>


<The first <name> node we get we create a Process_INfo and copy <name> in it and all other node following <name> till we get other <name> node. AS soon as we get a new <name> node we create a new <Process_Info> node amd repeat the previous process till we are done with all <name> nodes

I have to tranfrom this xsml using XSLT as,

<Process>
    <Process_Info>
        <name></name>
        <duration></duration>
        <time></time>
    </Process_Info>
    <Process_Info>
        <name></name>
        <duration></duration>
        <time></time>
    </Process_Info>
    ..
    ..
    ..
    ..        
</Process>


Can you please let me know how we can do this???
2
Contributors
5
Replies
6
Views
5 Years
Discussion Span
Last Post by Mike Askew
0

The XSLT works by storing all the XML within <Process> root node allowing access to it within the <name> for-each selects.

Within each for-each we get the position() of the <name> and then copy in the <time> and <duration> with the same positions.

XSLT

<xsl:stylesheet version="1.0" 
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>

  <xsl:variable name ="varProcess" select ="Process"/>

  <xsl:template match="Process">
    <xsl:element name="Process">
      <xsl:for-each select ="name">
        <xsl:variable name ="varPosition" select ="position()"/>
        <xsl:element name ="Process_Info">
          <xsl:copy-of select ="."/>
          <xsl:copy-of select="$varProcess/duration[$varPosition]"/>
          <xsl:copy-of select="$varProcess/time[$varPosition]"/>
        </xsl:element>
      </xsl:for-each>
    </xsl:element>
  </xsl:template>

</xsl:stylesheet>

INPUT

<Process>
  <name>Pro1</name>
  <duration>Dur1</duration>
  <time>Time1</time>
  <name>Pro2</name>
  <duration>Dur2</duration>
  <time>Time2</time>
  <name>Pro3</name>
  <duration>Dur3</duration>
  <time>Time3</time>
  <name>Pro4</name>
  <duration>Dur4</duration>
  <time>Time4</time>
  <name>Pro5</name>
  <duration>Dur5</duration>
  <time>Time5</time>
</Process>

OUTPUT

<Process>
  <Process_Info>
    <name>Pro1</name>
    <duration>Dur1</duration>
    <time>Time1</time>
  </Process_Info>
  <Process_Info>
    <name>Pro2</name>
    <duration>Dur2</duration>
    <time>Time2</time>
  </Process_Info>
  <Process_Info>
    <name>Pro3</name>
    <duration>Dur3</duration>
    <time>Time3</time>
  </Process_Info>
  <Process_Info>
    <name>Pro4</name>
    <duration>Dur4</duration>
    <time>Time4</time>
  </Process_Info>
  <Process_Info>
    <name>Pro5</name>
    <duration>Dur5</duration>
    <time>Time5</time>
  </Process_Info>
</Process>

Edited by Mike Askew

0

Hi Mike,

   The <name> node will be there for sure. But the other two nodes are optional. Tey may come or may not come. will the solution work in this case?

Thanks

0

The below XSLT works regardless of node occurance.

Credit to nonnb on StackOverflow.
Route to solution if interested: http://stackoverflow.com/questions/11537036/xslt-select-specific-nodes-below-current

XSLT

<xsl:stylesheet version="1.0" 
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>

  <xsl:template match="Process">
    <xsl:element name="Process">
      <xsl:for-each select ="name">
        <xsl:element name ="Process_Info">
          <xsl:copy-of select ="."/>
          <xsl:variable name="firstSib" select="local-name(following-sibling::*[1])" />
          <xsl:variable name="secondSib" select="local-name(following-sibling::*[2])" />
          <xsl:if test ="($firstSib='duration') or ($firstSib='time')">
            <xsl:copy-of select="following-sibling::*[1]"/>
          </xsl:if>
          <xsl:if test ="($secondSib='duration') or ($secondSib='time')">
            <xsl:copy-of select="following-sibling::*[2]"/>
          </xsl:if>
        </xsl:element>
      </xsl:for-each>
    </xsl:element>
  </xsl:template>
</xsl:stylesheet>

Edited by Mike Askew

This topic has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.