cancel
Showing results for 
Search instead for 
Did you mean: 

How to remove the message type (MT_) node and the prefix (ns1:)

Former Member
0 Kudos

Hi Gurus,

The following is the response message i am getting after the mapping

<ns1:MT_MATRES>

<MATERIAL_DETAILS>

<MATERIAL>MAT</MATERIAL>

<MATL_DESC> stainless steel</MATL_DESC>

<MATL_TYPE>ROH</MATL_TYPE>

<MATL_GROUP>FILES</MATL_GROUP>

<GROSS_WT>0</GROSS_WT>

<NET_WEIGHT>0</NET_WEIGHT>

<BASE_UOM>KG</BASE_UOM>

<PUR_GROUP/>

<STD_PRICE>0</STD_PRICE>

<PRICE_UNIT>0</PRICE_UNIT>

</MATERIAL_DETAILS>

<RETURN>

<TYPE>S</TYPE>

<CODE/>

<MESSAGE/>

</RETURN>

</ns1:MT_MATRES>

I want to remove the <ns1:MT_MATRES> node from the above response message and send the rest to an external system.

How can i remove it?

Thanks,

Prabu

Accepted Solutions (1)

Accepted Solutions (1)

maciej_jarecki
Contributor
0 Kudos

Hi

use this module in your adapter before standard adapter module

AF_Modules/XMLAnonymizerBean as local EB and following key anonymizer.acceptNamespaces

Regards

M.

Answers (5)

Answers (5)

Former Member
0 Kudos

Check the below thread:

Thanks,

stefan_grube
Active Contributor
0 Kudos

You can remove the namespace declaration and the namepsace prefix, when you go to your message type and remove the entry in the field XML Namespace.

If you want to rename the root name, rename the message type, as the message type name is the root name.

Former Member
0 Kudos

Thanks all for you replies.

The requirement has changed a little and i have opened a new thread "return a response based on condition" for that, I would request you post your answers for that as well.

Still all you answers will be helpful to me and other newbies.

Thank you all once again for you support.

Former Member
0 Kudos

Hi All,

After some changes in the requirements and configurations the scenario has changed a little bit.

My response message will be in either of the following structure based on a condition (without name space detail)

<MT_MATRES>

<MATERIAL_DETAILS>

<MATERIAL>MAT</MATERIAL>

<MATL_DESC> stainless steel</MATL_DESC>

<MATL_TYPE>ROH</MATL_TYPE>

<MATL_GROUP>FILES</MATL_GROUP>

<GROSS_WT>0</GROSS_WT>

<NET_WEIGHT>0</NET_WEIGHT>

<BASE_UOM>KG</BASE_UOM>

<PUR_GROUP/>

<STD_PRICE>0</STD_PRICE>

<PRICE_UNIT>0</PRICE_UNIT>

</MATERIAL_DETAILS>

</MT_MATRES>

OR

<MT_MATRES>

<RETURN>

<TYPE>S</TYPE>

<CODE/>

<MESSAGE/>

</RETURN>

<MT_MATRES>

now i have to remove the root node <MT_MATRES> and send the rest with <MATERIAL_DETAILS> or <RETURN>; as the root node, let me know how it can be done.

Thanks,

Prabu

Shabarish_Nair
Active Contributor
0 Kudos

try - /people/shabarish.vijayakumar/blog/2010/05/07/quick-tips-dealing-with-namespaces-in-xipi

Former Member
0 Kudos

Thanks for the reply Shabarish.

The name space and prefix has been removed already, my requirement is to remove the root node.

for ex: the XML structure after a mapping will look like below

<detail>

<category>

<regular> </regular>

</category>

</detail>

I need to remove the <detail> element from the above structure and return the following

<category>

<regular> </regular>

</category>

Let me know how to do that using a XSLT mapping. Any other method also will do.

Thanks,

Prabu

Former Member
0 Kudos

useful suggestions will be appreciated.

Former Member
0 Kudos

I haven't tried this out, but since you have marked Shweta's solution as very useful, I would suggest to use the following java mapping. I have marked the changes in bold :

import java.io.*;

import java.util.*;

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

public class RemoveMessageType implements StreamTransformation {

String record=null;

String comment=null;

private Map param = null;

private AbstractTrace trace = null;

public void execute(InputStream in, OutputStream out) {

try {

DataInputStream stdin = new DataInputStream(in);

int length = getLengthFromStream(stdin);

stdin.reset();

byte[] buffer = getBytesFromStream(stdin);

String sub=null;

String str = new String(buffer);

String response = "";

String messageType = "<ns1:MT_MATRES>";

String responseEnd = "";

String messageTypeEnd = "</ns1:MT_MATRES>";

str = str.replaceAll(messageType,response);

str = str.replaceAll(messageTypeEnd,responseEnd);

out.write(str.getBytes());

out.close();

} catch (IOException e) {

}

}

public int getLengthFromStream(InputStream is ) throws

IOException{

int i = 0;

int length = 0;

try{

while ((i = is.read())> 0){

length ++;

}

}catch (ArrayIndexOutOfBoundsException e) {

e.printStackTrace();

}

return length;

}

public byte[] getBytesFromStream(InputStream is) throws

IOException {

// Create the byte array to hold the data

byte[] bytes = new bytegetLengthFromStream(is);

is.reset();

// Read in the bytes

int offset = 0;

int tmp = 0;

while (offset < bytes.length

&& (is.read(bytes, offset, offset +

(tmp = is.available()))) > 0) {

offset += tmp;

}

// Ensure all the bytes have been read in

if (offset < bytes.length) {

throw new IOException("Could not completely read Inputstream");

}

// Close the input stream and return bytes

is.close();

return bytes;

}

public void setParameter (Map param) {

this.param = param;

if (param == null) {

this.param = new HashMap();

}

}

}

Regards,

TK

Former Member
0 Kudos

Thanks Sameej.

Let me know where to deploy this as my response mapping is as follows

BAPI.Response-->Response

Response has the resultant structure as below, from which <MT_MATRES> has to be stripped.

<MT_MATRES>

<element1>

<element1_1></element1_1>

</element1>

</MT_MATRES>

Note the element names may change dynamically (that part is already taken care in the response mapping).

The Idea is to remove the wrapper root node.

Thanks,

Prabu

stefan_grube
Active Contributor
0 Kudos

> Note the element names may change dynamically (that part is already taken care in the response mapping).

>

> The Idea is to remove the wrapper root node.

My idea is that you discuss that structure again.

A response message should have a unique root node.

When you have several possible root nodes for a response, that is a bad design.

As PI expert you have to influence the design of the interfaces, if business people want to use bad design, you have to prevent this.

Former Member
0 Kudos

Hi Stefan,

The idea is to return success or error details for an entity based on the condition.

The resultant structure is the output of mapping using CREATEIF which we've discussed in the below thread

[url]

Everything is working fine but the message type wraps the output structure as the root node which I wan to remove.

This is necessary because we don't have a luxury to change the .NET interfaces which sends the request and gets response from PI. Hope you understand the situation.

Let me know a good solution and I am ready to start over.

Thanks,

Prabu

Former Member
0 Kudos

Hi All,

Solved it myself using XSLT mapping.

I have not renamed the root but removed it.

For people like me who may need it in future, this is how i did it.

used the following XSL mapping after the final graphical mapping in the response (from BAPI)

***************************************************************************

<xsl:template match="/">

<xsl:for-each select="/Response/Mat_det">

<xsl:element name="Mat_det">

<xsl:element name="Mat_desc">

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

</xsl:element>

<xsl:element name="Mat_type">

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

</xsl:element>

</xsl:element>

</xsl:for-each>

<xsl:for-each select="/Response/ErrorDetails">

<xsl:element name="ErrorDetails">

<xsl:element name="ErrorCode">

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

</xsl:element>

<xsl:element name="ErrorMessage">

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

</xsl:element>

</xsl:element>

</xsl:for-each>

</xsl:template>

**********************************************************************************

Thanks for your encouraging answers

Prabu

former_member181985
Active Contributor
0 Kudos

You can use Java or XSLT mapping to perform this.

Former Member
0 Kudos

Could you please tell me how can to do that using XSL.

Thanks,

Prabu

shweta_walaskar2
Contributor
0 Kudos

Hi Prabhu,

Please use following java mapping to replace MT_ with <response>:

import java.io.*;

import java.util.*;

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

public class RemoveMessageType implements StreamTransformation {

String record=null;

String comment=null;

private Map param = null;

private AbstractTrace trace = null;

public void execute(InputStream in, OutputStream out) {

try {

DataInputStream stdin = new DataInputStream(in);

int length = getLengthFromStream(stdin);

stdin.reset();

byte[] buffer = getBytesFromStream(stdin);

String sub=null;

String str = new String(buffer);

String response = "<response>";

String messageType = "<ns1:MT_MATRES>";

String responseEnd = "</response>";

String messageTypeEnd = "</ns1:MT_MATRES>";

str = str.replaceAll(messageType,response);

str = str.replaceAll(messageTypeEnd,responseEnd);

out.write(str.getBytes());

out.close();

} catch (IOException e) {

}

}

public int getLengthFromStream(InputStream is ) throws

IOException{

int i = 0;

int length = 0;

try{

while ((i = is.read())> 0){

length ++;

}

}catch (ArrayIndexOutOfBoundsException e) {

e.printStackTrace();

}

return length;

}

public byte[] getBytesFromStream(InputStream is) throws

IOException {

// Create the byte array to hold the data

byte[] bytes = new byte[getLengthFromStream(is)];

is.reset();

// Read in the bytes

int offset = 0;

int tmp = 0;

while (offset < bytes.length

&& (is.read(bytes, offset, offset +

(tmp = is.available()))) > 0) {

offset += tmp;

}

// Ensure all the bytes have been read in

if (offset < bytes.length) {

throw new IOException("Could not completely read Inputstream");

}

// Close the input stream and return bytes

is.close();

return bytes;

}

public void setParameter (Map param) {

this.param = param;

if (param == null) {

this.param = new HashMap();

}

}

}

Thanks.

Regards,

Shweta

shweta_walaskar2
Contributor
0 Kudos

Hi Prabhu,

This code is for XI3.0.

If you are working on higher version,kindly adapt the code accordingly.

Thanks.

Regards,

Shweta

Former Member
0 Kudos

I am working in PI 7.11

Former Member
0 Kudos

Hi,

Not sure you can have an XML document w/o a root node ! If you remove the MATRES root node, it will contain 2 main nodes ... To remove the namespace prefix, I think the MessageAnonymizerBean should make it (not fully sure about the bean name) ...

Rgds

Chris

Edited by: Christophe PFERTZEL on Oct 14, 2010 9:37 AM

Former Member
0 Kudos

Thanks for the quick reply Christophe.

is there any way to rename that root node i.e, as <response> instead of <ns1:MT_MATRES> (NOTE:without ns1:).

Prabu

former_member181985
Active Contributor
0 Kudos

Try this, I tested this in standalone mode and it is working.

import com.sap.aii.mapping.api.StreamTransformation;
import java.io.*;
import java.util.Map;
 
public class RemoveNodeSample
    implements StreamTransformation
{	
    public RemoveNodeSample()
    { } 
    public void setParameter(Map map1)
    {
        map = map1;
    } 

	public static void main(String args[])
	{
		try
		{
			FileInputStream fin = new FileInputStream(args[0]);
			FileOutputStream fout = new FileOutputStream(args[1]);
			RemoveNodeSample mapping = new RemoveNodeSample();
			mapping.execute(fin, fout);
		}
		catch (Exception e)
			{
				e.printStackTrace();
			}
	}
public void execute(InputStream inputstream, OutputStream outputstream)
    {
			int len = 0;
			int BUFFER = 2048;
			byte buf[] = new byte[BUFFER];
 
			try
			{
				ByteArrayOutputStream baos = new ByteArrayOutputStream();

 
				while ((len = inputstream.read(buf)) != -1)
					{
						baos.write(buf, 0, len);
					}	
				String line = new String(baos.toByteArray() );
				String removeNodes = line.substring(0, line.indexOf("<ns1:MT_MATRES>")) + line.substring(line.indexOf("<ns1:MT_MATRES>") + "<ns1:MT_MATRES>".length() , line.indexOf("</ns1:MT_MATRES>"));
				outputstream.write(removeNodes.getBytes());
				//System.out.println(removeNodes);

			}
			catch (Exception e)
			{
				e.printStackTrace();
			} 
    } 
    private Map map;
}

Edited by: Praveen Gujjeti on Oct 14, 2010 1:51 PM

rajasekhar_reddy14
Active Contributor
0 Kudos

one solution is create XSD , and use it in PI . in this cases you no need to create staructure manually, you will not find these tags in message.

Regards,

Raj