cancel
Showing results for 
Search instead for 
Did you mean: 

Add namespace prefix to namespace declaration only

former_member214137
Participant
0 Kudos

Hi,

I need help to be able to add a prefix to the namespace declaration only and not to the rest of the xml structure.

The imported file looks like this (I have truncated the structure):

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

<SalesReps xmlns="http://www.ABC.com.au/salesrepexport">

<Header>

<LastRunStartDateTime>2011Apr07 1930</LastRunStartDateTime>

<CurrentRunStartDateTime>2011Apr15 1930</CurrentRunStartDateTime>

PI wants it to look like below, otherwise it does not read the data.:

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

<ns1:SalesReps xmlns:ns1="http://www.ABC.com.au/salesrepexport">

<Header>

<LastRunStartDateTime>2011Apr07 1930</LastRunStartDateTime>

<CurrentRunStartDateTime>2011Apr15 1930</CurrentRunStartDateTime>

Using the anonymizer bean to add the prefix I get this:

<?xml version='1.0' encoding='utf-8'?>

<ns1:SalesReps xmlns:ns1='http://www.ABC.com.au/salesrepexport'>

<ns1:Header>

<ns1:LastRunStartDateTime>2011Apr07 1930</ns1:LastRunStartDateTime>

<ns1:CurrentRunStartDateTime>2011Apr15 1930</ns1:CurrentRunStartDateTime>

Can anyone suggest how to get this format

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

<ns1:SalesReps xmlns:ns1="http://www.ABC.com.au/salesrepexport">

<Header>

<LastRunStartDateTime>2011Apr07 1930</LastRunStartDateTime>

<CurrentRunStartDateTime>2011Apr15 1930</CurrentRunStartDateTime>

I have read a number of articles on using XSLT which don't directly sove my problem but give some insight into what I might need to do.

I will continue down this path until anyone can point me in the right direction.

thanks in advance

Julian

Accepted Solutions (1)

Accepted Solutions (1)

anupam_ghosh2
Active Contributor
0 Kudos

Hi Julian,

                you need java mapping to do the trick here. I assume you are working with PI 7.1 or above versions then the following code is enough to resolve your problem. I have tested it from my end.

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.InputStream;

import java.io.OutputStream;

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 org.w3c.dom.Document;

import org.w3c.dom.Element;

import org.w3c.dom.NamedNodeMap;

import org.w3c.dom.Node;

import org.w3c.dom.NodeList;

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

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

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

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

public class DOMParser1 extends AbstractTransformation{

          /**

           * @param args

           */

          static String payload="";

 

          public void execute(InputStream in, OutputStream out)throws Exception

          {

                    Document document;

                    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

                    DocumentBuilder builder = factory.newDocumentBuilder();

                    document = builder.parse(in);

                    Document docOut=builder.newDocument();

                  Node root=document.getDocumentElement();

                  Element targetRoot;

                  Node tChild;

                  targetRoot=(Element)docOut.createElement("ns1:"+root.getNodeName());

                  targetRoot.setAttribute("xmlns:ns1","http://www.ABC.com.au/salesrepexport");

                           NodeList l=root.getChildNodes();

                  for(int i=0;i<l.getLength();++i)

                  {

                            tChild=docOut.importNode(l.item(i),true);

                            targetRoot.appendChild(tChild);

                  }

                docOut.appendChild(targetRoot);

                TransformerFactory tf = TransformerFactory.newInstance();

                    Transformer transform = tf.newTransformer();

                    transform.transform(new DOMSource(docOut), new StreamResult(out));

          }

          @Override

          public void transform(TransformationInput arg0, TransformationOutput arg1)

                              throws StreamTransformationException {

                    // TODO Auto-generated method stub

                    try {

                              this.execute(arg0.getInputPayload().getInputStream(), arg1.getOutputPayload().getOutputStream());

                    } catch (Exception e) {

                              // TODO Auto-generated catch block

                              e.printStackTrace();

                    } 

             

          }

}

input xml

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

<SalesReps xmlns="http://www.ABC.com.au/salesrepexport">

<Header>

<LastRunStartDateTime>2011Apr07 1930</LastRunStartDateTime>

<CurrentRunStartDateTime>2011Apr15 1930</CurrentRunStartDateTime>

</Header>

</SalesReps>

output xml

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

<ns1:SalesReps xmlns:ns1="http://www.ABC.com.au/salesrepexport">

<Header>

<LastRunStartDateTime>2011Apr07 1930</LastRunStartDateTime>

<CurrentRunStartDateTime>2011Apr15 1930</CurrentRunStartDateTime>

</Header>

</ns1:SalesReps>

Hope this resolves the problem. you need to just  compile the java code and deploy in Operation mapping.

Regards

Anupam

former_member214137
Participant
0 Kudos

Hi Anupam,

Thanks for the suggestion. I haven't had to implement a java mapping before, so I am looking forward to having a go at this solution. I'll update this post with my results after I have done it.

regards

Julian

former_member214137
Participant
0 Kudos

Hi Anupam,

I was hoping you might be able to answer this question for me in regards to to the package I have created fo rthis mapping;

I am using NWDS 7.01.03 and developing for PI 7.1. I don't have jar file aii_map_api.jar but do have com.sap.xpi.ib.mapping.lib.jar; which according to http://wiki.sdn.sap.com/wiki/display/XI/XI+libraries+for+development is the correct jar file to use. I have added com.sap.xpi.ib.mapping.lib.jar as an external jar. When I compile the package I get the error message 'The import com.sap cannot be resolved' about the following declarations:

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

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

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

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

I suspect I am trying to run before I can walk here. In addition to any help with my problem above would you be able to point me to a primer where they use com.sap.xpi.ib.mapping.lib.jar as everything I have found so far uses aii_map_api.jar?

regards

Julian

anupam_ghosh2
Active Contributor
0 Kudos

Hi Julian,

                 you are using correct jar file but I guess you are not using correct java version to compile the code. Please install  j2sdk 1.5.0. Then right click on your project in NWDS and go to build path--->configure build path. Then there is a option called  add library ---->JRE system library -->execution environment------> set this to J2SE 1.5. Then recompile this code. You have added 

com.sap.xpi.ib.mapping.lib.jar as external jar file that is correct. I don't think you will face problem this time. After compilation right click on java source file and choose export--->java (jar file)--->select the proper source code you want to export and click two options on "export generated class files and resource" and "compress contents of the jar files". Type the destination folder where you need to save the file and later upload this file in PI server. Details of the process you can see my article

  http://wiki.sdn.sap.com/wiki/x/BQj2D

I wrote the article for PI 7.0 but the steps of deploying java mapping remains the same for higher versions of Pi as well. You need changes in external jar file and java version to 1.5 .

Hope this helps.

Regards

Anupam

former_member214137
Participant
0 Kudos

Hi Anupam,

Thanks for the quick reply. Currently I am using j2sdk 1.5.0.22, it was my understanding that this would be OK to use. I have downloaded the install package from Oracle for 1.5.0.0 but both the online and off line versions refuse to run giving the message 'installation package could not be opened'.

Not sure where to go from here. Any suggestions?

Julian

anupam_ghosh2
Active Contributor
0 Kudos

Hi Julian,

                Go to control panel from start menu of your computer ----> view by category---->uninstall java2 runtime environment and java2 sdk. Now for this error "'installation package could not be opened' there can be several reasons check this link http://java.com/en/download/help/error_installpackage.xml

Try installing java 1.5.0 after downloading from http://www.oracle.com/technetwork/java/archive-139210.html. Then try following the steps I have explained in my earlier post. You need to do a build/ recompile your project. No need to run it. The rest of the steps to upload the java mapping has been explained in my article.

Regards

Anupam 

former_member214137
Participant
0 Kudos

Hi Anupam,

Sorry for the late response, I have been away. Thanks for your help and time.

In the end I found the interface mapping was the cause of the error (joys of inheriting someone elses work )

regards

Julian

former_member194011
Participant
0 Kudos

This message was moderated.

Answers (2)

Answers (2)

iaki_vila
Active Contributor
0 Kudos

Hi Julian,

If you want to add namespace only to the root node, you could use the XSL mapping, it's the easiest way, in my opinion.

With this XML:

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

<SalesReps xmlns="http://www.ABC.com.au/salesrepexport">

    <Header>

        <LastRunStartDateTime>2011Apr07 1930</LastRunStartDateTime>

        <CurrentRunStartDateTime>2011Apr15 1930</CurrentRunStartDateTime>

        <moretags>a</moretags>

    </Header>

    <moretags>a</moretags>

</SalesReps>

You could use this XSL:

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

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

    <xsl:template match="/|comment()|processing-instruction()">

        <ns1:SalesReps xmlns:ns1="http://www.ABC.com.au/salesrepexport">

            <xsl:copy>

                <xsl:apply-templates/>

            </xsl:copy>

        </ns1:SalesReps>

    </xsl:template>

    <xsl:template match="*/child::*">

        <xsl:element name="{local-name()}">

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

        </xsl:element>

    </xsl:template>

    <xsl:template match="@*">

        <xsl:attribute name="{local-name()}"><xsl:value-of select="."/></xsl:attribute>

    </xsl:template>

</xsl:stylesheet>

And this is the output:

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

<ns1:SalesReps xmlns:ns1="http://www.ABC.com.au/salesrepexport">

    <Header>

        <LastRunStartDateTime>2011Apr07 1930</LastRunStartDateTime>

        <CurrentRunStartDateTime>2011Apr15 1930</CurrentRunStartDateTime>

        <moretags>a</moretags>

    </Header>

    <moretags>a</moretags>

</ns1:SalesReps>

Regards.

former_member214137
Participant
0 Kudos

Hi Iñaki,

Thanks for that. The XLST worked when testing in message mapping and operation mapping but not when used in an end to end test.

The inbound message payload displays the following:

Multiple colons are not allowed in a name. Error processing resource....

<ns:1:SalesReps xmlns:ns:1='http://www.ABC.com.au/salesrepexport'><ns:1:Header><ns:1...

The mapping is putting additional colons in the xml and is adding prefixes to each node, which I don't want.

Any ideas why what is occuring is happening?

FYI. I am using a two stage mapping with the xslt first and a simple graphical mapping second.

regards

Julian

iaki_vila
Active Contributor
0 Kudos

Hi Julian,

The mapping is putting additional colons in the xml

This a weird situation, have you detected in runtime when the incorrect colons are being putted?, after XSL mapping or after message mapping?. Could you share your PI inbound payload from sxmb_moni?, may be there is any little difference to design time and produce this issue.

and is adding prefixes to each node, which I don't want.

Try to put in the target xsd, on xs:schema tag, this: elementFormDefault="unqualified"

Regards.

Message was edited by: Iñaki Vila

former_member214137
Participant
0 Kudos

Hi Iñaki,

Sorry for the late repsonse but I have been away.

Issue resolved. Cause of problem was a mapping error.

FYI the the prefix addition was occuring after the XSL mapping. From what I read and could understand having the namespace prefix on every node does not mak ethe xml structure invlaid, so I am suprised PI won't accpet it.

Anyway time is precious, so I can't afford to spent any more time on this.

Thank you for your time and effort.

regards

Julian

stefan_grube
Active Contributor
0 Kudos

The simplest solution would using the AnonymizerBean to remove the namespace at all and create a messagetype without XML namespace.

The correct solution of course: Create an xsd with an external tool and upload it to PI and create a message type based on it.

An XML document with or without namespace prefix or semantically different, so PI will not accept it.

markangelo_dihiansan
Active Contributor
0 Kudos

Hello,

The imported file looks like this (I have truncated the structure):

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

<SalesReps xmlns="http://www.ABC.com.au/salesrepexport">

<Header>

<LastRunStartDateTime>2011Apr07 1930</LastRunStartDateTime>

<CurrentRunStartDateTime>2011Apr15 1930</CurrentRunStartDateTime>

PI wants it to look like below, otherwise it does not read the data.:

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

<ns1:SalesReps xmlns:ns1="http://www.ABC.com.au/salesrepexport">

<Header>

<LastRunStartDateTime>2011Apr07 1930</LastRunStartDateTime>

<CurrentRunStartDateTime>2011Apr15 1930</CurrentRunStartDateTime>

What happens when you remove the entry from XML namespace in your message type?

    

If you are using an external definition, setting elementFormDefault="unqualified" in the ED would do the trick.

Hope this helps,

Mark

former_member214137
Participant
0 Kudos

Hi Mark,

Thanks for the suggestion. I had used this approach before but it did not work this time.

regards

Julian