cancel
Showing results for 
Search instead for 
Did you mean: 

How to split an xml field to N fields using PI Mapping ?

Former Member
0 Kudos

Hello Guys,

I have to split an xml field from Data Type IN_response  to 2 fields of my Data Type OUT_response and I dont know how to do this using PI Mapping.

It's something like this:

Data Type IN_RESPONSE with values (source):

     <XML_RESULT><os_code>34</os_code><os_type>TP</os_type></XML_RESULT>

Data Type OUT_RESPONSE (considering the values above, should be like this) (target):

     <RESULT>

           <OS_CODE>34</OS_CODE>

           <OS_TYPE>TP</OS_TYPE>

     </RESULT>

Do you know how can I obtain this result (target) having 1 string field  (that comes separated by tags <></> ) on the source side and 2 fields on the target using PI 7.3 Mapping?

Thank you so much.

Luciana R.

Accepted Solutions (1)

Accepted Solutions (1)

Former Member
0 Kudos

Hello Luciana,

you can use Java Mapping or XSLT Mapping  then you will get your required out put.

first goto XSLT Mapping otherwise go to Java Mapping.

XSLT Mapping Logic:--

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

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

     

     <xsl:output method="xml" indent="yes"/>

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

         <xsl:copy>

              <xsl:apply-templates select="node() | @*"/>

         </xsl:copy>

    </xsl:template>

               

</xsl:stylesheet>

Java Mapping Logic :--

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.InputStream;

import java.io.OutputStream;

import java.util.Map;

import javax.xml.parsers.DocumentBuilder;

import javax.xml.parsers.DocumentBuilderFactory;

import javax.xml.transform.Transformer;

import javax.xml.transform.TransformerFactory;

import javax.xml.transform.dom.DOMSource;

import javax.xml.transform.stream.StreamResult;

import javax.xml.transform.OutputKeys;

import org.w3c.dom.Document;

import org.w3c.dom.Node;

import org.w3c.dom.NodeList;

import com.sap.aii.mapping.api.StreamTransformation;

import com.sap.aii.mapping.api.StreamTransformationException;

public class AddCRorLF  implements StreamTransformation{

   

    public void execute(InputStream in, OutputStream out)

            throws StreamTransformationException {

         try

          {

               DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

               factory.setNamespaceAware(true);

               DocumentBuilder builder = factory.newDocumentBuilder();

               Document doc = builder.parse(in);

               

               TransformerFactory tFactory = TransformerFactory.newInstance();

               Transformer t = tFactory.newTransformer();

               t.setOutputProperty(OutputKeys.INDENT, "yes");

               t.transform(new DOMSource(doc), new StreamResult(out));

          }

          catch(Exception e)

          {

               e.printStackTrace();

               throw new StreamTransformationException("Error During Mapping", e);

          }

       

    }

    public void setParameter(Map arg0) {

       

       

    }

}

Regards,

Bhaskar

Former Member
0 Kudos

Hello friends,

Thank you soooo sooo much.

I'll analyse all of the suggestions and test them to solve my problem.

I'll back to give you a feedback .

Best Regards,

Luciana

anupam_ghosh2
Active Contributor
0 Kudos

Hi Luciana,

                 I think with an UDF you can achieve the same results. Could you please try this UDF

public static String extractPayload(String a,String tag) throws StreamTransformationException

{

          if(a=="" || a==null )

          {

                         return a;

          }

          String beginTag="<"+tag+">",endTag="</"+tag+">";

          int i,j,l;

          i=a.indexOf(beginTag);

          l=beginTag.length();

          j=a.indexOf(endTag);

          if(i>=0 && i<j)

          {

                         a=a.substring(i+l,j);

          }

          return a;

}

Thus I would map like this

XML_RESULT--------------->\

                                       ---------->extractPayload-------->OS_CODE

CONSTANT(os_code)--->/

and

XML_RESULT-------------->\

                                      ---------->extractPayload-------->OS_TYPE

CONSTANT(os_type)--->/

You need to put tag names in constants in message mapping without any quotes(").

I think this will resolve the problem.

The UDF needs two inputs one the value in the field XML_RESULT and another the name of the XML tag whose value you need to extract. The second value is being supplied in form of constant as tag name is not expected to change over time.

Regards

Anupam

Former Member
0 Kudos

Hello Anupam ,

I'm using an UDF as you sent me, and it's working fine.

The problem is that I have a lot of fields (tags) and two of them, come as table.

So, I have this case:

<movs>

     <mov>

          <field1>oi</field1>

          <field2>oi</field2>

     </mov>

<mov>

          <field1>oi2</field1>

          <field2>oi2</field2>

     </mov>

</movs>

Do you know how can I replicate <mov> to the target side?

Thank you so much guys.

Thank you Jürgen

Regards,

Luciana R.

anupam_ghosh2
Active Contributor
0 Kudos

Hi Luciana,

                Could you please post the required target structure? I could not follow what is the expected output from the input XML you mentioned.

Regards

Anupam

Former Member
0 Kudos

Hello Anupam,

Thank you.

You've been so helpful.

That's my resource XML:

my mapping:

Mapping test:

Do you if it's possible to duplicate the subtree <movimento> during runtime?

Thank you.

Luciana R.

anupam_ghosh2
Active Contributor
0 Kudos

Hi Luciana,

                 I used an UDF to resolve your first question or requirement. Now the second one is complicated to be resolved using an UDF. The reason being not only value is to be sent to a target but also you need to create parent node of a tag in the target. Say for example you need to create "movimento" in the target xml first followed by populating value in its child nodes. Then I would suggest to go for java mapping. I do not think this present problem can be resolved using UDF as there are multiple occurrence of target parent and child nodes. I also suggest that you create a new thread for the second requirement,if possible, as the second requirement is quite different and complicated from the first one. You also need to post in second thread, the version of PI you are working on, the complete source XML , required target XML structure,namespace information in source and target XML  and a link to the this thread so that experts might refer to in case they want to see the screen shots. 

Regards

Anupam  

Former Member
0 Kudos

Hello Dear  Anupam,

I had to create a Java Mapping...

It's almost ok....hehe

Thank you so much!

Best regards,

Luciana R.

Former Member
0 Kudos

Hello Dear  Anupam,

I had to create a Java Mapping...

It's almost ok....hehe

Thank you so much!

Best regards,

Luciana R.

anupam_ghosh2
Active Contributor
0 Kudos

Hi Luciana,

                Glad to know that the problem was resolved.

Regards

Anupam

Answers (2)

Answers (2)

Former Member
0 Kudos

Hello Luciana,

The source message that you have posted looks like a correct xml document.

You can easily map this messages with a graphical mapping. You just need to create a corresponding data type for this xml document.

But let me guess... your problem is that the inner xml string is escaped with &lt; and &gt; right?

If this is the case, you could use a small XSL Stylesheet as a first mapping step to translated the excaped xml string into a real xml string. Then the output of this mapping would be exactly what is shown above.

In the stylesheet you can use either the escape-uri function or the replace function to restore the xml characters.

There are some examples on the web, but I didn't try them out.

First let me know if my guess regarding the escaping is right.

(use the source code view in the SXMB_MONI to find out).

Regards,

Jürgen

rajasekhar_reddy14
Active Contributor
0 Kudos

Remove   tags  <XML_RESULT> , </XML_RESULT> using java mapping  and make sure that java mapping output valid XML.

or

you have use substring functionality to split the file but this is not a stable solution.

Former Member
0 Kudos

Hello Raja,

Thank you for your replay.

The problem is that the Data Type IN_RESPONSE is not mine.

It's a partner web service result so I'm not able to change this.

The partner sends me a single string field which value is an xml.


Do you have any other idea?


Thank you.

Luciana R.

rajasekhar_reddy14
Active Contributor
0 Kudos

take input as one string from partner and need java mapping logic(regular expresion) to remove tags <XML_RESULT> , </XML_RESULT>. Then outout of java mapping is expected output.

are you clear?

former_member460664
Participant
0 Kudos

Dear Raja,

I have used Substring concept to split the input string. Why it is not the stable solution? Please let me know.  In my case I have received Plant_Sloc as one string from source side. I have to split this into 1) Plant 2) Sloc. Have I used correct one?

Thanks in advance

Regards,

Ashok.