cancel
Showing results for 
Search instead for 
Did you mean: 

XSLT Mapping Question

Former Member
0 Kudos

Hello,

i have following problem.

i want to map all double entrys in a XML Message.

for Example my soure document looks like that:


<rows>
  <row>
    <id>001<id>
    <value>1000</value>
  <row>
  <row>
    <id>002<id>
    <value>1020</value>
  <row>
  <row>
    <id>002<id>
    <value>1020</value>
  <row>
  <row>
    <id>003<id>
    <value>980</value>
  <row>
</rows>

what i want to select now... is only the double record.

target document should look like that:


<doublerows>
 <row>
 <id>002</id>
 <value>1020</value>
 <row>
</doublerows>

Any idea how i could handle that with a XSLT Mapping ?

Regards,

Robin

Accepted Solutions (0)

Answers (5)

Answers (5)

udo_martens
Active Contributor
0 Kudos

Hi Robin,

the last stylesheet gave the doublerows double out. As you see i have no really important tasks to do and so i looked for a <b>recursive</b> script, what is neccessary because of castrated XSL variables. The solution gave me some welcome satitisfaction in this poor Frankfurt:delete-the-leading-zeros-life

The script is working only if the source is sorted. So, you may be have to put a sorting style before that.

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

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">

<xsl:template match="/">

<doublerows>

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

<xsl:with-param name="ID" select="0"/>

<xsl:with-param name="POS" select="0"/>

</xsl:call-template>

</doublerows>

</xsl:template>

<xsl:template name="loop">

<xsl:param name="ID"/>

<xsl:param name="POS"/>

<xsl:for-each select="//row[id=$ID]">

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

<row>

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

</row>

</xsl:if>

</xsl:for-each>

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

<xsl:if test="position() = $POS+1">

<xsl:choose>

<xsl:when test="id!=$ID">

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

<xsl:with-param name="ID" select="id"/>

<xsl:with-param name="POS" select="position()"/>

</xsl:call-template>

</xsl:when>

<xsl:otherwise>

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

<xsl:with-param name="ID" select="0"/>

<xsl:with-param name="POS" select="position()"/>

</xsl:call-template>

</xsl:otherwise>

</xsl:choose>

</xsl:if>

</xsl:for-each>

</xsl:template>

</xsl:stylesheet>[/code]

Regards,

Udo

Former Member
0 Kudos

Thanks Udo..

I will check this out.

Greetings from den haag,

Robin

Former Member
0 Kudos

It works .. but my process is a little bit more tricky.

my target file has to look more like this:


<target>
 <normalrows>
  <row>
    <id>001<id>
    <value>1000</value>
  <row>
  <row>
    <id>003<id>
    <value>980</value>
  <row>
 <normalrows>
 <doublerows>
   <row>
    <id>002<id>
    <value>1020</value>
  <row>
 </doublerows>
</target>

And one Task more is .. that i don't know how many rows come... i have to sort out all rows which occurs more than one times... i could come 2, 3, 5 or whatever times.

I think there is no way arround Java

Regards,

Robin

udo_martens
Active Contributor
0 Kudos

Don't tease me with that bad, bad word! Just give me an hour..

udo_martens
Active Contributor
0 Kudos

Hi Robin,

hmm, not easy. Good stuff 4 boring Frankfurt. Wish to be in Holland. Coffeeshops and so on...

Your solution: [code]<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">

<xsl:template match="/">

<target>

<normalrows>

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

<xsl:with-param name="ID" select="0"/>

<xsl:with-param name="POS" select="0"/>

<xsl:with-param name="REPEAT" select="0"/>

</xsl:call-template>

</normalrows>

<doublerows>

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

<xsl:with-param name="ID" select="0"/>

<xsl:with-param name="POS" select="0"/>

<xsl:with-param name="REPEAT" select="0"/>

</xsl:call-template>

</doublerows>

</target>

</xsl:template>

<xsl:template name="loopN">

<xsl:param name="ID"/>

<xsl:param name="POS"/>

<xsl:param name="REPEAT"/>

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

<xsl:if test="position() = $POS+1">

<xsl:choose>

<xsl:when test="id!=$ID">

<xsl:if test="$REPEAT=0 and $ID!=0">

<row>

<id>

<xsl:value-of select="$ID"/>

</id>

<value>

<xsl:value-of select="../row/value[../id=$ID]"/>

</value>

</row>

</xsl:if>

<xsl:if test="$REPEAT=0 and position()=last()">

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

</xsl:if>

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

<xsl:with-param name="ID" select="id"/>

<xsl:with-param name="POS" select="position()"/>

<xsl:with-param name="REPEAT" select="0"/>

</xsl:call-template>

</xsl:when>

<xsl:otherwise>

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

<xsl:with-param name="ID" select="id"/>

<xsl:with-param name="POS" select="position()"/>

<xsl:with-param name="REPEAT" select="$REPEAT+1"/>

</xsl:call-template>

</xsl:otherwise>

</xsl:choose>

</xsl:if>

</xsl:for-each>

</xsl:template>

<xsl:template name="loop">

<xsl:param name="ID"/>

<xsl:param name="POS"/>

<xsl:param name="REPEAT"/>

<xsl:for-each select="//row[id=$ID]">

<xsl:if test="position()=2 and $REPEAT=0 ">

<row>

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

</row>

</xsl:if>

</xsl:for-each>

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

<xsl:if test="position() = $POS+1">

<xsl:choose>

<xsl:when test="id!=$ID">

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

<xsl:with-param name="ID" select="id"/>

<xsl:with-param name="POS" select="position()"/>

<xsl:with-param name="REPEAT" select="0"/>

</xsl:call-template>

</xsl:when>

<xsl:otherwise>

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

<xsl:with-param name="ID" select="id"/>

<xsl:with-param name="POS" select="position()"/>

<xsl:with-param name="REPEAT" select="$REPEAT+1"/>

</xsl:call-template>

</xsl:otherwise>

</xsl:choose>

</xsl:if>

</xsl:for-each>

</xsl:template>

</xsl:stylesheet>

[/code]

Regards,

Udo

Former Member
0 Kudos

Jesus!

Dude, that looks cool

i will look in detail tomorrow ...

Next company party i will spend you a beer

Thanks,

Robin

udo_martens
Active Contributor
0 Kudos

Hi Robin,

check this out:

[code]

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

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">

<xsl:template match="/">

<doublerows>

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

<xsl:variable name="ID" select="id"/>

<xsl:for-each select="../row[id=$ID]">

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

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

</xsl:if>

</xsl:for-each>

</xsl:for-each>

</doublerows>

</xsl:template>

</xsl:stylesheet>

[/code]

Regards,

Udo

Former Member
0 Kudos

Hi Robin,

Message was edited by: Anish Abraham

Former Member
0 Kudos

Hi Robin,

I suggest you to go for XSLT with Java enhancement. This will make your task easy. For more details on XSLT with Java enhancement please go through the following link.

http://help.sap.com/saphelp_nw2004s/helpdata/en/e2/e13fcd80fe47768df001a558ed10b6/frameset.htm

There is also a weblog for the XSLT mapping with Java enhancement. Please go through it.

/people/pooja.pandey/blog/2005/06/27/xslt-mapping-with-java-enhancement-for-beginners

Hope this will help you.

Thanks and Regards

Vishal Kumar

Former Member
0 Kudos

Hi,

You could collect all the elements with the <row> tag.

Put the values of all these tags into an array.

In a for loop, check which value is repeating, and create a <row>, <id>, <value> tags for the target, and insert the recurring value.

Regards,

Smitha.