cancel
Showing results for 
Search instead for 
Did you mean: 

Java Mapping help

former_member200386
Active Participant
0 Kudos

Dear Experts,

I have requirement where i need to add name space to element of external definition.

My Source XML format:

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

<sendSmsResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://abc.alarm.sxit.com">

   <sendSmsReturn>

      <respCode xmlns=""></respCode>

      <respMessage xmlns=""></respMessage>

   </sendSmsReturn>

</sendSmsResponse>

Desired Format:

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

<sendSmsResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://abc.alarm.sxit.com">

   <sendSmsReturn>

      <respCode xmlns="http://abc.alarm.sxit.com"></respCode>

      <respMessage xmlns="http://abc.alarm.sxit.com"></respMessage>

   </sendSmsReturn>

</sendSmsResponse>

I need add "http://abc.alarm.sxit.com"  to my element respcode and respmessage 

Below is the java code i used.

package com.ford.pi.javamap;

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.io.OutputStream;

import java.io.Reader;

import java.io.UnsupportedEncodingException;

import java.util.Map;

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

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

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

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

public class AppendNameSpaceToXML extends AbstractTransformation {

  private AbstractTrace trace;

  private Map param;

  private boolean isXI = false;

  private String ximsguid = "TESTCASE";

  private String namespaceDef = "";

  private String tempPayload = "";

  private String tempHeader = "";

  public void setParameter(Map param) {

  this.param = param;

  this.isXI = true;

  trace = (AbstractTrace) ((Map) param)

  .get(StreamTransformationConstants.MAPPING_TRACE);

  this.ximsguid = (String) ((Map) param)

  .get(StreamTransformationConstants.MESSAGE_ID);

  }

  public void transform(TransformationInput arg0, TransformationOutput arg1)

  throws StreamTransformationException {

  try {

  if (isXI) {

  trace.addInfo("Adding Namespace in to xml response");

  }

  String inputXML = convertStreamToString(arg0.getInputPayload()

  .getInputStream());

  String temp = null;

  StringBuffer sb = new StringBuffer();

  if (inputXML != null || inputXML.length() > 0) {

  inputXML = inputXML.replaceAll("xmlns=\"\"",

  "xmlns=\"http://abc.alarm.sxit.com\"");

  }

  if (isXI) {

  trace.addInfo("Adding Namespace in to xml response");

  }

  try {

  // 8. The JAVA mapping output payload is returned using the

  // TransformationOutput class

  // arg1.getOutputPayload().getOutputStream()

  arg1.getOutputPayload().getOutputStream()

  .write(inputXML.getBytes("UTF-8"));

  } catch (Exception exception1) {

  }

  } catch (Exception e) {

  // TODO Auto-generated catch block

  throw new StreamTransformationException("Error adding the namespace", e);

  }

  }

  public String convertStreamToString(InputStream in) {

  StringBuffer sb = new StringBuffer();

  try {

  InputStreamReader isr = new InputStreamReader(in);

  Reader reader = new BufferedReader(isr);

  int ch;

  while ((ch = in.read()) > -1) {

  sb.append((char) ch);

  }

  reader.close();

  } catch (Exception exception) {

  }

  return sb.toString();

  }

}

I am getting below error.

        Class com/ford/pi/javamap/AppendNameSpaceToXML (urn:ford-com:SMSIntegration_SoapLookup, -1, 6e09c940-ea70-11e5-c03b-ce03136ea367) does not implement the required interface com.sap.aii.mapping.api.StreamTransformation or does not enhance the class com.sap.aii.mapping.api.AbstractTransformation

See error logs for details    

I am using PI 7.4 single stack version. Please help me on this regard.

Thanks,

Pavan T

Accepted Solutions (1)

Accepted Solutions (1)

former_member190293
Active Contributor
0 Kudos

Hi Pavan!

As Sreenivas has already mentioned above you could use simple XSL transformation:

<?xml version='1.0'?>

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

<xsl:template match="/">

     <sendSmsResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

                                    xmlns:xsd="http://www.w3.org/2001/XMLSchema"

                                    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"

                                    xmlns="http://abc.alarm.sxit.com">

          <sendSmsReturn>

               <respCode> <xsl:value-of select="//respCode"/> </respCode>

               <respMessage> <xsl:value-of select="//respMessage"/> </respMessage>

          </sendSmsReturn>

     </sendSmsResponse>

</xsl:template>

</xsl:stylesheet>

It's worth mention that actually you don't need to set namespace for your "respCode" and "respMessage" elements because default namespace "http://abc.alarm.sxit.com" has already been declared in "sendSmsResponse" element so element itself and all underlying elements belong to default namespace unless element is qualified with other namespace explicitely.

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

<sendSmsResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://abc.alarm.sxit.com">

   <sendSmsReturn> [ marked with xmlns="http://abc.alarm.sxit.com" ]

      <respCode xmlns="http://abc.alarm.sxit.com"></respCode> [ marked with xmlns="http://abc.alarm.sxit.com" ]

      <respMessage xmlns="http://abc.alarm.sxit.com"></respMessage> [ marked with xmlns="http://abc.alarm.sxit.com" ]

   </sendSmsReturn>

</sendSmsResponse>

Regards, Evgeniy.

former_member200386
Active Participant
0 Kudos

Hi Evgeniy,

Thanks for the response, I tried your XSLT code.It's not working .After XSLT mapping step now xmlns=" " is getting removed, Still elements are in red color.Please find the details below.

former_member190293
Active Contributor
0 Kudos

Ok, try this:

<?xml version='1.0'?>

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

<xsl:template match="/">

     <ns0:sendSmsResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

                                    xmlns:xsd="http://www.w3.org/2001/XMLSchema"

                                    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"

                                   xmlns:ns0="http://abc.alarm.sxit.com">

          <sendSmsReturn>

               <respCode> <xsl:value-of select="//respCode"/> </respCode>

               <respMessage> <xsl:value-of select="//respMessage"/> </respMessage>

          </sendSmsReturn>

     </ns0:sendSmsResponse>

</xsl:template>

</xsl:stylesheet>

And please provide XML view of your test XML message from screenshot (SRC button). I mean default test instance.

Regards, Evgeniy.

former_member200386
Active Participant
0 Kudos

Hi Evgeniy,

This code also not working. As requested, Please find the test instance xml below.

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

<ns0:sendSmsResponse xmlns:ns0="http://abc.alarm.sxit.com">

   <ns0:sendSmsReturn>

      <ns1:respCode xmlns:ns1="http://model.webservice.alarm.sxit.com"/>

      <ns1:respMessage xmlns:ns1="http://model.webservice.alarm.sxit.com"/>

   </ns0:sendSmsReturn>

</ns0:sendSmsResponse>

former_member190293
Active Contributor
0 Kudos

Ok. Let's try this:

<?xml version='1.0'?>

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

                                                    xmlns:ns0="http://abc.alarm.sxit.com"

                                                    xmlns:ns1="http://model.webservice.alarm.sxit.com">

<xsl:template match="/">

     <ns0:sendSmsResponse>

          <ns0:sendSmsReturn>

               <ns1:respCode> <xsl:value-of select="//respCode"/> </ns1:respCode>

               <ns1:respMessage> <xsl:value-of select="//respMessage"/> </ns1:respMessage>

          </ns0:sendSmsReturn>

     </ns0:sendSmsResponse>

</xsl:template>

</xsl:stylesheet>

Regards, Evgeniy.

former_member200386
Active Participant
0 Kudos

Hi Evgeniy,

Thanks for the help. Latest code is worked out for me. Hence closing this thread.

Answers (2)

Answers (2)

former_member191435
Contributor
0 Kudos
former_member190293
Active Contributor
0 Kudos

Hi Pavan!

I think that you don't need java mapping for your requirement as you can do it in graphical mapping:

Regards, Evgeniy.

former_member200386
Active Participant
0 Kudos

Hi Evgeniy,

Thanks for the quick response. I can't go with solution which you provided. Here is problem. The input i am receiving from target application don't have the namespace in the attributes. So i am not able to populate the data into target side . Here is the issue.

If you look into attached screen shots. because of the name space is missing to the fields (resp code, respmessage) structure turned into red and i am getting mapping exception( these two are mandatory

I need to add the namespace to those fields before message mapping step. That is the reason why i am using java mapping.

Thanks,

Pavan T

markangelo_dihiansan
Active Contributor
0 Kudos

Hi Pavan,


I need to add the namespace to those fields before message mapping step. That is the reason why i am using java mapping.

Have you tried removing the namespaces via XMLAnonymizerBean? That way you do not have to use java or xslt mapping.

Regards,

Mark

former_member190293
Active Contributor
0 Kudos

Hi Mark!

I've just tried XMLAnonymizerBean with parameter anonymizer.acceptNamespaces set to:

http://www.w3.org/2001/XMLSchema-instance xsi http://www.w3.org/2001/XMLSchema xsd http://schemas.xmlsoap.org/soap/envelope/ soapenv http://abc.alarm.sxit.com ''

And it doesn't remove empty namespace definition.

Maybe I didn't set parameter right?

Regards, Evgeniy.

markangelo_dihiansan
Active Contributor
0 Kudos

Hi Evgeniy,

Actually, there is no need to place anything on the acceptNamespaces It get removed.

Regards,

Mark

former_member190293
Active Contributor
0 Kudos

Hi Mark!

But if I leave acceptNamespaces blank it will completely remove all namespaces from document. Or I'm wrong?

Regards, Evgeniy.

markangelo_dihiansan
Active Contributor
0 Kudos

Hi Evgeniy,

Yes you are correct, it will completely remove it.

Regards,

Mark

former_member190293
Active Contributor
0 Kudos

Hi Mark!

But as I could understand requirement was to qualify "respCode" and "respMessage" elements with particular namespace, not to remove namespaces from document.

Or did I miss anything?

Regards, Evgeniy.

markangelo_dihiansan
Active Contributor
0 Kudos

Hi Evgeniy,

I figured <respCode xmlns=""></respCode> and <respCode></respCode> should be semantically equal Hence I suggested to use XMLAnonymizerBean. But I could be wrong, I do not have a validator with me at the moment.

Regards

Mark

former_member190293
Active Contributor
0 Kudos

Hi Mark!

I see But I guess those elements are needed to be qualified with "http://abc.alarm.sxit.com" namespace.

Just thought if I missed anything according to XMLAnonymizerBean .

Regards, Evgeniy

markangelo_dihiansan
Active Contributor
0 Kudos

Hi Evgeniy,

Here's an interesting discovery, I imported the expected XML and PI added ns0 to ALL of the fields which makes it look like it has a targetnamespace and it is elementFormDefault="qualified". XLST/Java is needed for this.

Regards,

Mark

former_member190293
Active Contributor
0 Kudos

Hi Mark!

I remember, we've already talked about PI unusual behavour in case of default namespaces and namespaces without prefixes.

It looks a bit strange to me when message:

<Message xmlns='urn://test'>

     <Item1/>

     <Item2/>

</Message>

is represented in PI like:

<ns0:Message ns0:xmlns='urn://test'>

     <ns0:Item1/>

     <ns0:Item2/>

</ns0:Message>

Regards, Evgeniy.

markangelo_dihiansan
Active Contributor
0 Kudos

Hi Evgeniy,

Yes, I remember that one where you also have to adjust the xpath even if there are no prefixes. But I've seen one document that the two are equal if the xmlns is declared in the root node. If it is just inside a child e.g

<Message>

     <Item1 xmlns='urn://test'/>

     <Item2 xmlns='urn://test'/>

</Message>

is equal to

<Message>

     <Item1/>

     <Item2/>

</Message>

Regards,

Mark