简体   繁体   中英

How to parse nested nodes in xml to csv in java

I may be overlooking the solution here, but I need help converting xml to csv with multiple nested nodes. The xml I am given looks like the following sample:

<?xml version="1.0"?>
<familyResponse>
  <results>
    <childResults>
      <childName>Mary</childName>
      <childAge>8</childAge>
    </childResults>
    <childResults>
      <childName>Jason</childName>
      <childAge>10</childAge>
    </childResults>
    <childResults>
      <childName>Ashley</childName>
      <childAge>15</childAge>
    </childResults>
    <parentResults>
      <parentName>Theresa</parentName>
      <parentAge>35</parentAge>
    </parentResults>
  </results>
  <results>
    <parentResults>
      <parentName>Tom</parentName>
      <parentAge>21</parentAge>
    </parentResults>
  </results>
  <results>
    <childResults>
      <childName>Tori</childName>
      <childAge>2</childAge>
    </childResults>
    <parentResults>
      <parentName>Sheila</parentName>
      <parentAge>19</parentAge>
    </parentResults>
  </results>
</familyResponse>

There will always be a parentResults with 1 entry. There may not always be a childResults entry and there can also be multiple childResults entries. If there is no childResults entry, I don't need to put the parentResults in the file, I want my csv file to look like the following:

parentName,parentAge,childName,childAge
Theresa,35,Mary,8
Theresa,35,Jason,10
Theresa,35,Ashley,15
Sheila,19,Tori,2

I already have my java code together and can parse the xml but I need help handling the nested nodes.

In my xsl file, I tried doing this:

<xsl:template match="/">parentName,parentAge,childName,childAge
  <xsl:for-each select="//results>
    <xsl:value-of select="concat(parentResults/parentName,',',parentResults/parentAge,',',childResults/childName,',',childResults/childAge,'&#xA;')"/>
  </xsl:for-each>
</xsl:template>

But that gave me:

parentName,parentAge,childName,childAge
Theresa,35,Mary,8
Sheila,19,Tori,2

I also tried this:

<xsl:template match="/">parentName,parentAge,childName,childAge
  <xsl:for-each select="//results>
    <xsl:for-each select="//childResults>
      <xsl:value-of select="concat(parentResults/parentName,',',parentResults/parentAge,',',childName,',',childAge,'&#xA;')"/>
    </xsl:for-each>
  </xsl:for-each>
</xsl:template>

But that gave me:

parentName,parentAge,childName,childAge
,,Mary,8
,,Jason,10
,,Ashley,15
,,Tori,2

I also tried this:

<xsl:template match="/">parentName,parentAge,childName,childAge
  <xsl:for-each select="//results>
    <xsl:for-each select="//parentResults>
      <xsl:value-of select="concat(parentName,',',parentAge)"/>
    </xsl:for-each>
    <xsl:for-each select="//childResults>
      <xsl:value-of select="concat(',',childName,',',childAge,'&#xA;')"/>
    </xsl:for-each>
  </xsl:for-each>
</xsl:template>

But that gave me:

parentName,parentAge,childName,childAge
Theresa,35,Mary,8
,,Jason,10
,,Ashley,15
Sheila,19,Tori,2

Thanks in advance.

Thanks dnault. I was able to figure out my problem with XSL but I'll also look at your suggestion of using a DOM parser. The change to my XSL to get it to work is:

<xsl:template match="/">parentName,parentAge,childName,childAge
  <xsl:for-each select="//results>
    <xsl:for-each select="//childResults>
      <xsl:value-of select="concat(../parentResults/parentName,',',../parentResults/parentAge,',',childName,',',childAge,'&#xA;')"/>
    </xsl:for-each>
  </xsl:for-each>
</xsl:template>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM