Skip to Content
0

Map XML Element Names as value of XML Elements

Jan 31, 2017 at 03:53 PM

61

avatar image

Dear Mapping Experts,

I have a source XML that looks something like this:

<root><element><dog>OK</dog><cat>KO</cat><sheep/><snake>OK</snake></element><element><cat>OK</cat><horse/></element><element><sheep>KO</sheep><snake>OK</snake><horse>OK</horse><bird>KO</bird></element></root>

I need to convert it into this format:

<root><list><element><animals><name>dog</name><value>OK</value></animals><animals><name>cat</name><value>KO</value></animals><animals><name>sheep</name><value/></animals><animals><name>snake</name><value>OK</value></animals></element><element><animals><name>cat</name><value>OK</value></animals><animals><name>horse</name><value/></animals></element><element><animals><name>sheep</name><value>KO</value></animals><animals><name>snake</name><value>OK</value></animals><animals><name>horse</name><value>OK</value></animals><animals><name>bird</name><value>KO</value></animals></element></list></root>

So I need to get the element names and their values in the source XML and map them to the elements in the target XML.

Is it possible to do this via message mapping? If no, any tips for XSLT?

Thanks experts.

10 |10000 characters needed characters left characters exceeded
* Please Login or Register to Answer, Follow or Comment.

1 Answer

Evgeniy Kolmakov Jan 31, 2017 at 07:18 PM
0

Hi Mike!

<?xml version="1.0" encoding="UTF-8"?>
http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output indent="yes"/>
<xsl:template match="/">
<root>
<list>
<xsl:apply-templates/>
</list>
</root>
</xsl:template>
<xsl:template match="element">
<element>
<xsl:for-each select="*">
<animals>
<name> <xsl:value-of select="local-name()"/> </name>
<value> <xsl:value-of select="text()"/> </value>
</animals>
</xsl:for-each>
</element>
</xsl:template>
<xsl:template match="text()|@*"/>
</xsl:stylesheet>

Regards, Evgeniy.

Show 2 Share
10 |10000 characters needed characters left characters exceeded

Evgeniy - hi!

Thank you much. Super helpful. What does the last template mean? Because it still works even if I remove it.

<xsl:template match="text()|@*"/>

Also, if there is a new element called <isSnake> that will be populated if <snake> exists in the source and its value as shown in the code. How to achieve?

<root>
 <list>
  <element>
   <isSnake>OK</isSnake>
   <animals>
    <name>dog</name>
    <value>OK</value>
   </animals>
   <animals>
    <name>cat</name>
    <value>KO</value>
   </animals>
   <animals>
    <name>sheep</name>
    <value/>
   </animals>
   <animals>
    <name>snake</name>
    <value>OK</value>
   </animals>
  </element>
  <element>
   <animals>
    <name>cat</name>
    <value>OK</value>
   </animals>
   <animals>
    <name>horse</name>
    <value/>
   </animals>
  </element>
  <element>
   <isSnake>OK</isSnake>
   <animals>
    <name>sheep</name>
    <value>KO</value>
   </animals>
   <animals>
    <name>snake</name>
    <value>OK</value>
   </animals>
   <animals>
    <name>horse</name>
    <value>OK</value>
   </animals>
   <animals>
    <name>bird</name>
    <value>KO</value>
   </animals>
  </element>
 </list>
</root>

I try adding this line but it just gets all values of <snake>

<isSnake><br> <xsl:for-each select="/root/element/snake"><br> <xsl:value-of select="text()"/><br> </xsl:for-each><br> </isSnake>
0

Evgeny - hi!

I solve it. I add following code

<xsl:if test="snake">
<xsl:for-each select="snake">
<isSnake>
<xsl:value-of select="text()"/>
</isSnake>
</xsl:for-each>
</xsl:if>

Feel free to advise if there's a better approach. Thanks lots!

0