Skip to Content

Add namespace prefix to namespace declaration only

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

Add comment
10|10000 characters needed characters exceeded

  • Get RSS Feed

3 Answers

  • Best Answer
    Oct 22, 2012 at 10:15 AM

    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

    Add comment
    10|10000 characters needed characters exceeded

  • Oct 23, 2012 at 08:42 AM

    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.

    Add comment
    10|10000 characters needed characters exceeded

    • 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.

  • Oct 22, 2012 at 07:06 AM

    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

    Add comment
    10|10000 characters needed characters exceeded