Skip to main content
Announcements
July 15, NEW Customer Portal: Initial launch will improve how you submit Support Cases. IMPORTANT DETAILS
cancel
Showing results for 
Search instead for 
Did you mean: 
Anonymous
Not applicable

A need to unflatten xml

I have the following challenge:

I have a webservice that returns the following inside a job

<response>
  <result>
    <title>something</title>
    <timestamp>sometimestamp</timestamp>
    <tag1>tag1value</tag1>
    <tag2>tag2value</tag2>
    <tag3>tag3value</tag3>
    <tag4>tag4value</tag4>
    ....
  </result>
</response>

And i need to change it to the following

<Report>
  <tagValues>
    <tagValue>
      <timestamp>sometimestamp</timestamp>
      <tagname>tag1</tagname>
      <value>tag1value</value>
    </tagValue>
    <tagValue>
      <timestamp>sometimestamp</timestamp>
      <tagname>tag2</tagname>
      <value>tag2value</value>
    </tagValue>
    <tagValue>
      <timestamp>sometimestamp</timestamp>
      <tagname>tag3</tagname>
      <value>tag3value</value>
    </tagValue>
    <tagValue>
      <timestamp>sometimestamp</timestamp>
      <tagname>tag4</tagname>
      <value>tag4value</value>
    </tagValue>
    ...
  </tagValues>
</report>

Is that at all possible?

Labels (3)
1 Solution

Accepted Solutions
Donatien1
Partner - Contributor III
Partner - Contributor III

I don't know if it's easier to make a loop on each tag with the tXMLMap.

I think that the better way is to use XSL Transformation with a tXSLT component.

 

The content of the XSL file should be like this.

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

  <xsl:template match="/">
     <Report>
        <tagValues>
           <xsl:for-each select="/response/result/**">
               <xsl:if test="name() != 'title' and name() != 'timestamp'">
                  <tagValue>
                      <timestamp><xsl:value-of select="/response/result/timestamp"/></timestamp>
                      <tagname><xsl:value-of select="name()"/></tagname>
                      <value><xsl:value-of select="."/></value>
                  </tagValue>
               </xsl:if>
           </xsl:for-each>
        </tagValues>
     </Report>
  </xsl:template>
</xsl:stylesheet>

View solution in original post

5 Replies
fdenis
Creator III
Creator III

you may use tXmlMap were you can define or modify schema of your xml.
when you have select tXmlMap Componet on your job you can press F1 to have help and samples
Donatien1
Partner - Contributor III
Partner - Contributor III

I don't know if it's easier to make a loop on each tag with the tXMLMap.

I think that the better way is to use XSL Transformation with a tXSLT component.

 

The content of the XSL file should be like this.

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

  <xsl:template match="/">
     <Report>
        <tagValues>
           <xsl:for-each select="/response/result/**">
               <xsl:if test="name() != 'title' and name() != 'timestamp'">
                  <tagValue>
                      <timestamp><xsl:value-of select="/response/result/timestamp"/></timestamp>
                      <tagname><xsl:value-of select="name()"/></tagname>
                      <value><xsl:value-of select="."/></value>
                  </tagValue>
               </xsl:if>
           </xsl:for-each>
        </tagValues>
     </Report>
  </xsl:template>
</xsl:stylesheet>
Anonymous
Not applicable
Author

The XSLT sounds good.

Is there a way to apply XSLT in Talend without going through the tXSLT component (and it's need for files) for instance in a tJavaRow?

fdenis
Creator III
Creator III

you can use javax.xml to do it on tJavarow or tjava or tJavaFlex
but think about person who is going to reopen your job.
with tjavaxxx he have to read your code
with tXLST he know that it's xml transformer
Donatien1
Partner - Contributor III
Partner - Contributor III

Yes it should be possible to do this in java in tJavaRow.

I think you can adapt the code present in the following link : https://gist.github.com/serge1/9307868

You just need to generate a source with a String, but I think it's possible.

 

To me, the code is very easy to understand, so I think it's not a bad way to use a tJavaRow if you don't want to write your XML in a file.