Handling DOCTYPE tag in PI
This document will be useful for the all PI developers, especially for those who are not familiar with XSLT, Java or ABAP mappings. This document guides them to easily handle the scenario that is going to be discussed in further sections.
In typical SAP implementation, while developing PI interfaces most of the cases we observe that the clients guide us to re-use the existing XSD/DTDs of legacy systems for integration. In such scenarios, sometimes we notice that in the XSD/DTD provided by the client will have a <DOCTYPE> tag in the definition. Even though we import the definition as External Definitions in PI and can see this tag, PI will not consider this while runtime or design time (Message Types and Mappings) either.
If the Legacy system is a Source system in integration, we will get the message with this tag to PI and since PI will not consider this tag in message type, the message fails. For this scenario SAP has provided a note 812966 to handle the situation.
If the Legacy system is a target system, we are forced to generate the DOCTYPE tag in outgoing XML message from PI. Since SAP has not yet provided any solution out-of the box, this document helps us to handle this situation with ease, considering performance aspect.
The standard PI message mapping will not support this addition of DOCTYPE tag white mapping source to target messages; hence we are left with options to go for Java, XSLT or ABAP mappings.
Let us evaluate these options:
Java or XSLT Mappings:
Most of the clients will not support these solutions as these will cause performance issues especially in high volume scenarios. Also, these options need a specialized knowledge and maintenance.
Since many of the clients moving away from dual-stack and using AAE or AEX to configure the scenarios for better performance, we might get a push back from client for this solution as well.
Based on above analysis, by now we might get confused that we have no options left. But we do have seamless solution which is easily achievable and will not impact the performance. All we need to do is design a message mapping and on top of it add a XSLT mapping to add the DOCTYPE tag.
We can debate that the same can be achieved with Java or ABAP mappings or Adapter Modules also, but in Java or ABAP mappings we need to traverse through entire message XML and build the output message XML. Adapter modules need a specialized knowledge and maintenance troublesome. But XSLT will provide us an option to add the DOCTYPE tag without actually parsing the entire XML and minimal coding effort.
Even for the PI developers who are not hands on XSLT mappings, can use this solution and it is pretty easy to understand as explained in below section.
To understand this XSLT mapping solution better, let us consider following use case:
Let’s say client provided us a DTD with vendor details which needs to be mapped from CREMAS IDOC from ECC, generate the target XML and transfer to the third party file server. Since this DTD has a DOCTYPE tag, the third party expects the incoming XML message also will have this tag.
The above scenario is detailed below:
Let us import the DTD in ESR and check the DOCTYPE tag:
Message Type and details look like below:
However after Message Mapping step, PI will not include the DOCTYPE tag in the output message XML, as shown below:
Hence, we will add XSLT mapping (will be discussed in below pages), on top of Message Mapping while defining Operation Mapping step as shown below:
Let us execute the Operation Mapping and check the result. It should add DOCTYPE now to target message.
Please note that once we execute the Operation Mapping due to addition of DOCTYPE tag, PI will throw a message like “Unable to generate the tree view”, please ignore and check XML view of the message as shown below:
<?xml version=”1.0″ encoding=”UTF-8″?>
<xsl:stylesheet version=”1.0″ xmlns:xsl=”http://www.w3.org/1999/XSL/Transform“>
<!– Add the DOCTYPE tag –>
<xsl:output method=”xml” version=”1.0″ encoding=”UTF-8″ indent=”yes”
<!– Copy over the source XML to the output without any changes –>
<xsl:template match=”node() | @*”>
<xsl:apply-templates select=”node() | @*”/>
Now, let us understand what we have done in the above XSLT mapping:
<xsl:stylesheet> or <xsl:transform> are the root elements that declare the document to be an XSL style sheet. Either of the two elements can be used as root elements as they are synonymous. The namespace xmlns:xsl=”http://www.w3.org/1999/XSL/Transform” points to the official W3C XSLT namespace. If you use this namespace, you must also include the attribute version=”1.0″
The <xsl:output> element defines the format of the output document. This is a top-level element, and must appear as a child node of <xsl:stylesheet> or <xsl:transform>. Here XSLT gives the flexibility to add DOCTYPE to the output as seen in the above mapping
An XSL style sheet contains one or more set of rules that are called templates. A template contains rules to apply when a specified node(s)/attribute(s) are matched. The “match” attribute is used to associate a template with an XML element or it can also be used to define a template for the entire XML document. The value of the match attribute is an XPath expression, in this case we used “node() | @*, mentioning that to consider all nodes and attributes of source.
The <xsl:copy> element creates a copy of the current node. In our case it’s the template having entire nodes and attributes.
The <xsl:apply-templates> element applies a template to the current element or to the current element’s child nodes. If we add a select attribute to the <xsl:apply-templates> element it will process only the child element that matches the value of the attribute. We can use the select attribute to specify the order in which the child nodes are processed. In our case it will be entire hierarchy of nodes and attributes.