cancel
Showing results for 
Search instead for 
Did you mean: 

Mapping: Fitting managers into rooms ?

Former Member
0 Kudos

Hello All, The below map is disinclined to acquiesce to my request; translation: itz knot verkin.

I'm trying to fit the 'managers' in the source into 'room's in the target. Assuming a max of 4 rooms, I want them filled up with 4 managers per room (with some rooms remaining empty and not showing up in the target).

I'm learning how to map currently. Thanks for your help.

SOURCE:

<?xml version="1.0" encoding="UTF-8"?>

<ns0:s2 xmlns:ns0="urn://maptest">

<managers>

<personalID>PID001</personalID>

<personalID>PID002</personalID>

<personalID>PID003</personalID>

<personalID>PID004</personalID>

<personalID>PID005</personalID>

<personalID>PID006</personalID>

<personalID>PID007</personalID>

</managers>

</ns0:s2>

MAPPING:

???

After the map runs, the target produced SHOULD look as follows:

TARGET:

<?xml version="1.0" encoding="UTF-8"?>

<ns0:t2 xmlns:ns0="urn://maptest">

<room>

<personalID>PID001</personalID>

<personalID>PID002</personalID>

<personalID>PID003</personalID>

<personalID>PID004</personalID>

</room>

<room>

<personalID>PID005</personalID>

<personalID>PID006</personalID>

<personalID>PID007</personalID>

</room>

</ns0:t2>

In the source, managers is 1..1, while personalID is 0..unbounded.

In the target, room is 0..4, while personalID is 1..4.

Thanks, Bhishma

Accepted Solutions (1)

Accepted Solutions (1)

Former Member
0 Kudos

Refer to the Weblog

'Message Splitting Using the Graphical Mapping Tool'

/people/claus.wallacher/blog/2006/06/29/message-splitting-using-the-graphical-mapping-tool

which will help you to Split the source message.

Former Member
0 Kudos

Thank you Henrique & Stefan; both your solutions worked well. Much appreciated.

John, I'm reviewing your link now for understanding this graphical monkey.

Ciao, Bhishma

Former Member
0 Kudos

Henrique, Stefan, John, THANK YOU !

I have learnt so much in this 1 post; The map is now willing to acquiesce to my request !

Here's the graphical map:

/ns0:t2=/ns0:s2=

/ns0:t2/room=collapseContexts(SplitByValue([type=Value changed]floor(div(index([start=0, inc=1, type=context]/ns0:s2/managers/personalID=), const([value=4])))))

/ns0:t2/room/personalID=formatByExample(/ns0:s2/managers/personalID=, SplitByValue([type=Value changed]floor(div(index([start=0, inc=1, type=context]/ns0:s2/managers/personalID=), const([value=4])))))

At this point I have an understanding of contexts & most of the built-in functions. Lots more to learn; let the games begin !

Ciao, Bhishma

Answers (2)

Answers (2)

stefan_grube
Active Contributor
0 Kudos

You can do this with two UDF (cache context):

public void createRooms(String[] a,ResultList result,Container container){
  for (int k=0; k<(a.length+3)/4; k++)
    result.addValue("");
}

public void distibuteManagers(String[] a,ResultList result,Container container){
  for (int k=0;k<a.length;k++){
    result.addValue(a[k]);
    if (k%4==3&&k<a.length)
      result.addContextChange();
  }
}

Do the mapping that way:

personalID - createRooms - room
personalID - distributeManagers - personalID

Regards

Stefan

henrique_pinto
Active Contributor
0 Kudos

Yay Stefan!

Nice information.

Regards,

Henrique.

henrique_pinto
Active Contributor
0 Kudos

Dude,

I'm in the final phase of the project where I don't get much to do, so I spend the whole day studying new stuff. =D

Your example sure was a hell of an exercise on XSLT.

Try this mapping on your scenario.

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns0="urn://maptest">

<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:param name="managers"/>

<xsl:template match="/">

<xsl:param name="managers" select="//personalID"/>

<ns0:t2>

<xsl:call-template name="rooms">

<xsl:with-param name="managers" select="$managers"/>

</xsl:call-template>

</ns0:t2>

</xsl:template>

<xsl:template name="rooms">

<xsl:param name="managers"/>

<xsl:call-template name="add_room">

<xsl:with-param name="managers" select="subsequence($managers, 1, 4)"/>

</xsl:call-template>

<xsl:if test="not(empty(subsequence($managers, 5)))">

<xsl:call-template name="rooms">

<xsl:with-param name="managers" select="subsequence($managers, 5)"/>

</xsl:call-template>

</xsl:if>

</xsl:template>

<xsl:template name="add_room">

<xsl:param name="managers"/>

<room>

<xsl:for-each select="$managers">

<xsl:copy-of select="."/>

</xsl:for-each>

</room>

</xsl:template>

</xsl:stylesheet>

Former Member
0 Kudos

Hello Henrique, Thanks for your reply. Glad I could help keep you busy!

I figured out how to plug in your xsl map (hence the delay in response) and it's throwing the below error:

javax.xml.transform.TransformerException: com.sap.engine.lib.xml.util.NestedException: Function with name 'subsequence' not found in context library. at com.sap.engine.lib.jaxp.TransformerImpl.transform(TransformerImpl.java:245) at com.sap.aii.ibrun.server.mapping.MappingTransformer.transform(MappingTransformer.java:153) at....(& so on).

I don't know xlst and hence can't debug the above, but I get the idea....but thanks for giving the sol'n since it forced me to figure out how to plug in xsl maps.

I'm good with java though and can do the map in java in 15 mins.

So the question is, can the below be mapped using just the graphical editor (node functions et al.) ? It's these that I was trying to solve this problem using.

Ciao, Bhishma

henrique_pinto
Active Contributor
0 Kudos

I had tested it in XMLSpy but didn't test on XI. Sorry for that. You can do the same idea on Java Mapping and it also should work.

Performing Graphical Mapping it should be more complicated. Try to understand the queues and using type = context.

Regards,

Henrique.

Former Member
0 Kudos

Thanks; will continue the search for the holy grail.

Ciao, Bhishma

henrique_pinto
Active Contributor
0 Kudos

New retry:

try this ugly-but-possibly-XI-compliant XSLT

(I didn't test it because I'm at home; will test it tomorrow)

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns0="urn://maptest">

<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/">

<ns0:t2>

<xsl:for-each select="//personalID">

<xsl:if test="position() mod 4 = 1">

<xsl:text disable-output-escaping="yes"><![CDATA[<room>]]></xsl:text>

</xsl:if>

<xsl:copy-of select="."/>

<xsl:choose>

<xsl:when test="position() mod 4 = 0">

<xsl:text disable-output-escaping="yes"><![CDATA[</room>]]></xsl:text>

</xsl:when>

<xsl:otherwise>

<xsl:if test="position() = last()">

<xsl:text disable-output-escaping="yes"><![CDATA[</room>]]></xsl:text>

</xsl:if>

</xsl:otherwise>

</xsl:choose>

</xsl:for-each>

</ns0:t2>

</xsl:template>

</xsl:stylesheet>

Regards,

Henrique.