Converting xml using xsl

77 Views Asked by At

i trying to work with xml with multiple properties witch looks like that

  <AllNames name="John">
    <dates>
      <date day="20150126" country="uk" fruit="kiwi">PP</rank>
      <date day="20150227" country="uk" fruit="coconut">PP</rank>
    </dates>
  </AllNames>
  <AllNames name="Michael">
      <dates>
      <date day="20150126" country="uk" fruit="apple">XX</rank>
      <date day="20150127" country="uk" fruit="orange">YY</rank>
    </dates>
  </AllNames>

i want my result to look like that:

John, 20150126 , uk , kiwi,PP

John, 20150227 , uk , coconut,PP

Michael,20150126, uk , apple,XX

Michael,20150127, uk , orange,YY

i have tried this code which dosnt work at all please help me

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text" />
<xsl:variable name="delimiter" select="','" />
<xsl:variable name="fieldArray">
    <field>name</field>
    <field>day</field>
    <field>country</field>
    <field>fruit</field>
  </xsl:variable>
  <xsl:param name="fields" select="document('')/*/xsl:variable[@name='fieldArray']/*" />

  <xsl:template match="/">
         <xsl:for-each select="$fields">
      <xsl:if test="position() != 1">
        <xsl:value-of select="$delimiter"/>
      </xsl:if>
      <xsl:value-of select="." />
    </xsl:for-each>
 <xsl:text>
</xsl:text>
  <xsl:apply-templates select="AllNames/name"/>
  </xsl:template>

  <xsl:template match="rank">
    <xsl:variable name="currNode" select="." />

    <xsl:for-each select="$fields">
      <xsl:if test="position() != 1">
        <xsl:value-of select="$delimiter"/>
      </xsl:if>
      <xsl:value-of select="$currNode/*[name() = current()]" />
    </xsl:for-each>
        <xsl:text>
</xsl:text>
  </xsl:template>
</xsl:stylesheet>
1

There are 1 best solutions below

2
michael.hor257k On BEST ANSWER

Your input is still not well-formed XML. If you had an input such as:

XML

<root>
   <entry name="John">
      <dates>
         <date day="20150126" country="uk" fruit="kiwi">AA</date>
         <date day="20150227" country="uk" fruit="coconut">BB</date>
      </dates>
   </entry>
   <entry name="Michael">
      <dates>
         <date day="20150126" country="uk" fruit="apple">XX</date>
         <date day="20150127" country="uk" fruit="orange">YY</date>
      </dates>
   </entry>
</root>

you could use:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>

<xsl:template match="/root">
    <xsl:for-each select="entry/dates/date">
        <xsl:value-of select="../../@name" />
        <xsl:text>,</xsl:text>
        <xsl:value-of select="@day" />
        <xsl:text>,</xsl:text>
        <xsl:value-of select="@country" />
        <xsl:text>,</xsl:text>
        <xsl:value-of select="@fruit" />
        <xsl:text>,</xsl:text>
        <xsl:value-of select="." />
        <xsl:text>&#10;</xsl:text>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

to get:

John,20150126,uk,kiwi,AA
John,20150227,uk,coconut,BB
Michael,20150126,uk,apple,XX
Michael,20150127,uk,orange,YY