xml-xsl transformation

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • sgxbytes
    New Member
    • Sep 2008
    • 25

    #1

    xml-xsl transformation

    Hi,

    Source format:
    <d1 name="a1">
    <d2 name="b1">
    <d3 name="c1"/>
    </d2>
    <d2 name="b2">
    <d3 name="c2"/>
    </d2>
    </d1>
    <d1 name="a2">
    <d2 name="b3">
    <d3 name="c3"/>
    <d3 name="c4"/>
    </d2>
    </d1>


    Output format:
    <row d1="a1" d2="b1" d3="c1" />
    <row d1="a1" d2="b2" d3="c2" />
    <row d1="a2" d2="b3" d3="c3" />
    <row d1="a2" d2="b3" d3="c4" />


    The twist is that the source xml is created dynamic and any tag can be used to idetify a new row to be created in output xml.In above example you can see that first part of source xml the d2 tag was used to as seperation to create a new row and in second part of source xml he tag d3 act as deciding factor to create a new row.
    As the source xml is dynamic any tag from d1,d2,d3,d(n).. .... can be deciding factor for creation of new row in output xml.

    how can i go ahead with this

    raj
  • Dormilich
    Recognized Expert Expert
    • Aug 2008
    • 8694

    #2
    if the element which is empty creates the new row, simply check for child elements
    [CODE=xml]<xsl:if test="self::*[not(child::node ())]">
    // make new row here
    </xsl:if>[/CODE]you could possibly put it into a <xsl:template > too

    regards

    Comment

    • jkmyoung
      Recognized Expert Top Contributor
      • Mar 2006
      • 2057

      #3
      With respect to above comment, could simplifying just by using the d3 node. There is one node per d3 node.
      This assumes the data is ordered by d1, then d2, then d3.

      Work backwards from d3 nodes:
      [code=xml]
      <xsl:for-each select="//d3">
      <row d1="{preceding: :d1[1]/@name}" d2="{preceding: :d1[1]/@name}" d3="{@name}"/>
      [/code]

      Comment

      • Dormilich
        Recognized Expert Expert
        • Aug 2008
        • 8694

        #4
        Originally posted by sgxbytes
        As the source xml is dynamic any tag from d1,d2,d3,d(n).. .... can be deciding factor for creation of new row in output xml.
        @ jkmyoung: but how do you find the last element, if you don't know it's name? (probably you have to loop to get all <row> attributes for an unknown number of elements)

        regards

        Comment

        • jkmyoung
          Recognized Expert Top Contributor
          • Mar 2006
          • 2057

          #5
          Sorry, misread that part. Expanded upon your solution by adding the preceding: axis. Now when I look at it again, it is really:
          [code=xml]
          <xsl:for-each select="//*[not (*)]">
          <row>
          <xsl:for-each select="ancesto r-or-self::*">
          <xsl:attribut e name="{name()}" ><xsl:value-of select="@name"/></xsl:attribute>
          </xsl:for-each>
          </row>
          </xsl:for-each>
          [/code]

          Use the ancestor-or-self::axis. Note that this will put the attributes in backwards, but in true xml, attribute order does not matter.

          Comment

          Working...