cancel
Showing results for 
Search instead for 
Did you mean: 

Replace escaped characters using XSLT 1.0

0 Kudos

Hi Gurus,

I have a requirement wherein I need to replace the escaped characters  using xslt ver 1.0. I can't seem to get it to work.

The scenario is:

1. Normal message mapping

2. Result of 1. will be mapped to a field in another mapping

3. result of 2. will be passed to an xslt to escape the characters

Here is the code for the xslt:

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

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:ns0="http://sap.com/xi/XI/SplitAndMerge"

xmlns:ns1="urn:novonordisk.com:Z_NN_SAP_E9:SerialNumberManagement">

  <xsl:template match="*">

    <xsl:text disable-output-escaping="no">&lt;</xsl:text>

    <xsl:value-of select="name()"/>

    <xsl:apply-templates select="@*"/>

    <xsl:text disable-output-escaping="no">&gt;</xsl:text>

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

    <xsl:text disable-output-escaping="no">&lt;/</xsl:text>

    <xsl:value-of select="name()"/>

    <xsl:text disable-output-escaping="no">&gt;</xsl:text>

  </xsl:template>

  <xsl:template match="@*">

    <xsl:text disable-output-escaping="no">&#32;</xsl:text>

    <xsl:value-of select="name()" disable-output-escaping="no"/>

    <xsl:text disable-output-escaping="yes">=&amp;quot;</xsl:text>

    <xsl:value-of select="." disable-output-escaping="no"/>

    <xsl:text disable-output-escaping="yes">&amp;quot;</xsl:text>

  </xsl:template>

  <xsl:template match="ns0:Messages | ns0:Message1 | ns1:DataHeader | ns1:data | ns1:TrackingNo">

      <xsl:copy>

<xsl:apply-templates select="@*"/>

<xsl:apply-templates/>

</xsl:copy>

  </xsl:template>

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

<xsl:copy-of select="replace(., '&amp;', '&amp;amp;')"/>

  </xsl:template>

</xsl:stylesheet>



In the code above, I added the last part to replace &amp; with &amp;amp;. This is the characters accepted by the receiver system. I have to this for the other escaped characters as well.

&quot; - &amp;quot;

&apos; - &amp;apos;

&lt; - &amp;lt;

&gt; - &amp;gt;


For now I'm only testing &amp;amp; . But I will be extremely grateful if we can replace the escaped characters i mentioned above


Thanks Sirs

Accepted Solutions (1)

Accepted Solutions (1)

former_member190293
Active Contributor

Hi SAPenthusiast!

Please provide source message (or its fragment) and desired output.

Regards, Evgeniy.

0 Kudos

Source message from result of step 2:

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

<ns0:Messages xmlns:ns0="http://sap.com/xi/XI/SplitAndMerge">

   <ns0:Message1>

<ns1:DataHeader xmlns:ns1="urn:xxx.com:Z_xx_SAP_xx:Interface">

<ns1:data>

<Parameters type="CustomerMaster" Reference="1000000001">

<Customer>XXX &amp; 32/F TOWER</Customer>

</Parameters>

</ns1:dataString>

<ns1:TrackingNo>DataHeader_XXX_1000000001_09012016_084900</ns1:TrackingNo>

      </ns1: DataHeader>

   </ns0:Message1>

</ns0:Messages>

Current Target output in step 3:

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

<ns0:Messages xmlns:ns0="http://sap.com/xi/XI/SplitAndMerge">

<ns0:Message1>

<ns1:DataHeader xmlns:ns1="urn:xxx.com:Z_xx_SAP_xx:Interface">

<ns1:data>&lt;Parameters type=&quot;CustomerMaster&quot; Reference=&quot;1000000001&quot;&gt;&lt;Customer&gt;XXX &amp; 32/F TOWER&lt;/Customer&gt;&lt;/Parameters&gt;</ns1:dataString><ns1:TrackingNo>DataHeader_XXX_1000000001_09012016_084900</ns1:TrackingNo></ns1:DataHeader></ns0:Message1></ns0:Messages>

Desired Target output

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

<ns0:Messages xmlns:ns0="http://sap.com/xi/XI/SplitAndMerge">

<ns0:Message1>

<ns1:DataHeader xmlns:ns1="urn:xxx.com:Z_xx_SAP_xx:Interface">

<ns1:data>&lt;Parameters type=&quot;CustomerMaster&quot; Reference=&quot;1000000001&quot;&gt;&lt;Customer&gt;XXX &amp;amp; 32/F TOWER&lt;/Customer&gt;&lt;/Parameters&gt;</ns1:dataString><ns1:TrackingNo>DataHeader_XXX_1000000001_09012016_084900</ns1:TrackingNo></ns1:DataHeader></ns0:Message1></ns0:Messages>

0 Kudos

Hi SAPenthusiast,

Do you really need XSLT to handle this? Can't u handle the same via UDF?

0 Kudos

We actually have plenty of fields. We need to scan the whole XML document for &amp; and replace it with &amp;amp;

former_member190293
Active Contributor
0 Kudos

As far as I could understand you use XSLT 2.0

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

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns1="urn:xxx.com:Z_xx_SAP_xx:Interface"

    version="2.0">

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

        <xsl:copy>

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

        </xsl:copy>

    </xsl:template>

   

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

        <xsl:copy/>

    </xsl:template>

   

    <xsl:template match="//ns1:dataString">

        <xsl:variable name="apos">'</xsl:variable>

        <ns1:dataString>

            <xsl:value-of select="replace(replace(replace(replace(replace(text(),'&amp;','&amp;amp;'),'&quot;','&amp;quot;'),'&lt;','&amp;lt;'),'&gt;','&amp;gt;'),$apos,'&amp;apos;')"/>

        </ns1:dataString>

    </xsl:template>

   

</xsl:stylesheet>

You have two different elements: "data" and "dataString" in provided structure. I assume, that you use "dataString".

Regards, Evgeniy.

Former Member
0 Kudos

Hi SAPenthusiast,


I achieved the same kind requirement using java mapping. You can use below code.


package com.Javamapping;

import java.io.*;

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

public class WellFormedXml_JavaMapping extends AbstractTransformation {

  @Override

    public void transform(TransformationInput transformationInput, TransformationOutput transformationOutput) throws StreamTransformationException {

        try {

            InputStream inputstream = transformationInput.getInputPayload().getInputStream();

            OutputStream outputstream = transformationOutput.getOutputPayload().getOutputStream();

            // Copy Input content to String

            byte[] b = new byte[inputstream.available()];

            inputstream.read(b);

            String inputContent = new String(b);

            inputContent = inputContent.replaceAll("&amp;", "&amp;amp;");

            outputstream.write(inputContent.getBytes());

        } catch (Exception exception) {

            getTrace().addDebugMessage(exception.getMessage());

            throw new StreamTransformationException(exception.toString());

        }

    }

  }

I can forward you the Jar file.


0 Kudos

I'll try this out and will give an update. Thanks Evgeniy!

0 Kudos

Thanks Tanuja

Can you send it via mail? Or can we attach here?

If via mail, kindly send to reivaxavier02@yahoo.com Thanks!!!

Former Member
0 Kudos

Sent mail. Import Jar file into imported archive and use that in your operation mapping

Former Member
0 Kudos

Here is the updated code. It fulfills remaining special characters as well.

package com.Javamapping;

import java.io.*; 

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

public class WellFormedXml_JavaMapping extends AbstractTransformation { 

  @Override 

     public void transform(TransformationInput transformationInput, TransformationOutput transformationOutput) throws StreamTransformationException { 

         try { 

             InputStream inputstream = transformationInput.getInputPayload().getInputStream(); 

             OutputStream outputstream = transformationOutput.getOutputPayload().getOutputStream(); 

             // Copy Input content to String 

             byte[] b = new byte[inputstream.available()]; 

             inputstream.read(b); 

             String inputContent = new String(b); 

             inputContent = inputContent.replaceAll("&", "&amp;");

             outputstream.write(inputContent.getBytes()); 

         } catch (Exception exception) { 

             getTrace().addDebugMessage(exception.getMessage()); 

             throw new StreamTransformationException(exception.toString()); 

         } 

     } 

  }

0 Kudos

Hi Tanuja I did not receive any mail. I checked both inbox and spam. it's reivaxavier02@yahoo.com. Thanks sir

0 Kudos

got it

0 Kudos

Hi Evgeniy,

I tried it but I got a Could not compile stylesheet error in the PI ESR test tab. Is it because the version is just 1.0? We're using 7.1 PI

former_member190293
Active Contributor
0 Kudos

Yes. It's XSLT 2.0 transformation.

From your XSL code I concluded that you used XSLT 2.0 as there was "replace()" function in your code.

Regards, Evgeniy.

former_member190293
Active Contributor
0 Kudos

Here is XSLT 1.0 transformation:

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

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns1="urn:xxx.com:Z_xx_SAP_xx:Interface" xmlns:my="urn://xslt_transformation" version="1.0">

    <xsl:output indent="yes"/>

   

    <my:params xml:space="preserve">

        <pattern>

            <old>&amp;</old>

            <new>&amp;amp;</new>

        </pattern>

        <pattern>

            <old>&quot;</old>

            <new>&amp;quot;</new>

        </pattern>

        <pattern>

            <old>&lt;</old>

            <new>&amp;lt;</new>

        </pattern>

        <pattern>

            <old>&gt;</old>

            <new>&amp;gt;</new>

        </pattern>

        <pattern>

            <old>&apos;</old>

            <new>&amp;apos;</new>

        </pattern>

    </my:params>

   

    <xsl:variable name="replacePatterns" select="document('')/*/my:params/*"/>

   

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

        <xsl:copy>

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

        </xsl:copy>

    </xsl:template>

   

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

        <xsl:copy/>

    </xsl:template>

   

    <xsl:template match="//ns1:dataString">

        <ns1:dataString>

            <xsl:call-template name="multiReplace"/>

        </ns1:dataString>

    </xsl:template>

   

    <xsl:template name="multiReplace">

        <xsl:param name="pText" select="."/>

        <xsl:param name="pPatterns" select="$replacePatterns"/>

       

        <xsl:if test="string-length($pText)>0">

            <xsl:variable name="foundPattern" select="$replacePatterns[starts-with($pText, old)][1]"/>

            <xsl:choose>

                <xsl:when test="not($foundPattern)">

                    <xsl:copy-of select="substring($pText,1,1)"/>

                </xsl:when>

                <xsl:otherwise>

                    <xsl:copy-of select="$foundPattern/new/node()"/>

                </xsl:otherwise>

            </xsl:choose>

            <xsl:call-template name="multiReplace">

                <xsl:with-param name="pText" select="substring($pText, 1 + not($foundPattern) + string-length($foundPattern/old/node()))"/>

            </xsl:call-template>

        </xsl:if>

    </xsl:template>


</xsl:stylesheet>

Regards, Evgeniy.

0 Kudos

Thanks Evgeniy. I'll try this out and give an update later

Answers (0)