Sunteți pe pagina 1din 40

Java Mapping

Training Courseware

Java Mapping

Bibinu
SAP-XI Consultant,
Capgemini Consulting India Pvt Ltd,
Vikhroli, Mumbai.
________________________
Phone +91 (0) 022-66496332
Fax +91 (0)22 5555 7000
_________________________

Reference: Java Mapping V1.0.doc

Page 1 of 40

Training Courseware

Java Mapping

TABLE OF CONTENTS

1.0 Scope.......................................................................................
2.0 What is Java Mapping..............................................................
3.0 Pre-requisite for Java Mapping.................................................
3.1 Mapping API............................................................................
3.2 SAX Parser..............................................................................
3.3 DOM Parser.............................................................................
4.0 When to use Java mapping in XI?...........................................
4.1 How is Java mapping different from Graphical, XSLT and ABAP
mapping?........................................................................................
4.2 Advantages of using Java mapping.............................................
4.3 Disadvantages of using Java mapping.........................................
5.0 SAP NetWeaver Developer Studio and Tools.................................
6.0 Steps for implementing Java mapping in XI..............................
7.0 Examples...............................................................................
7.1 Example 1 XML to XML (Using SAX Parser)..............................
7.2 Example 2 XML to XML (Using SAX Parser)..............................
7.3 Example 3 XML to XML (Using DOM Parser).............................
7.4 Example 4 XML to Text (Using DOM Parser).............................
7.5 Example 5 XML to HTML (Using SAX Parser)............................
7.6 Example 6 Text to XML ........................................................
8.0 When to use SAX and DOM parsers?........................................
9.0 References.............................................................................
i)
Links....................................................................................
ii)
SDN Weblogs/SAP help............................................................

Reference: Java Mapping V1.0.doc

Page 2 of 40

Training Courseware

1.0

Java Mapping

Scope
This document provides details you'll need to know about getting started
with the Java mapping. It also gives an overview regarding how to process XML
documents using Java API for XML Processing (JAXP). The JAXP supports the
Document Object Model (DOM) and the Simple API for XML (SAX). This gives
you great flexibility for mapping definitions with Java.
Examples outlining different transformations are also provided.
Details about XI Design and Configuration are not under the scope of this
document.
Target Audience
The document is intended for XI consultants trying to learn Java mapping.
Prior Knowledge of XI development environment is essential.

Reference: Java Mapping V1.0.doc

Page 3 of 40

Training Courseware

2.0

Java Mapping

What is Java Mapping


It is a mapping program written in Java which implements a specific
interface of the mapping API which transforms any document into any required
format.
Some

3.0

of the transformations can be from,


XML to XML
XML to Text
XML to HTML
Text to XML
HTML to XML

Pre-requisites for Java Mapping


For Java mapping there is no development tool support in XI. It is
expected that they are developed using external development tools like Eclipse,
Jdeveloper, etc. To make the mapping available for the integration server, they
have to be imported into the integration repository as JAR files (JAR: Java
ARchives).
To be able to write a mapping program in your Java development
environment, the Java runtime environment (JRE) of the SAP J2EE server must
be consistent with the JRE version of your Java development environment. The
developer should also be aware of the java APIs which are to be used within a
mapping program. Since the program has to deal with an XML input, it should
understand and parse the data within the XML InputStream so that it could
manipulate it as per the requirement. Currently the most popular parser APIs
available for manipulating the XML Documents are SAX and DOM.
The java APIs which are to be used within a mapping program are;
3.1

Mapping API

The runtime environment for Java mappings has a mapping API. To use
Java mapping, you must define a Java class that implements the Java interface
com.sap.aii.mapping.api.StreamTransformation. This interface is available in
aii_map_api.jar. It has two methods:
...

public void execute(java.io.InputStream in,


java.io.OutputStream out)
At runtime, the Integration Engine calls this method to execute a
mapping. This method contains an input stream for the source document and an
output stream for the target document as parameters. These streams are usually
XML documents.

public void setParameter(java.util.Map param)

The Integration Engine transfers parameters to the mapping program with


this method. It evaluates these parameters at runtime in the method execute().
This enables you to control the process flow of the mapping.
Reference: Java Mapping V1.0.doc

Page 4 of 40

Training Courseware

Java Mapping

The transferred object that implements the Java interface java.util.Map


contains seven key/value pairs as parameters. These correspond to
corresponding fields in the message header. Apart from the MAPPING_TRACE
constant, the value objects are of type java.lang.String. The key objects are
defined in the class com.sap.aii.mapping.api.StreamTransformationConstants:
String Mapping Runtime Constants
Constant
MESSAGE_CLASS

Meaning
Classification of message. Possible values

ApplicationMessage:
Asynchronous or synchronous request
message

ApplicationResponse:
Response to a request message

SystemAck, ApplicationAck, SystemError,


ApplicationError

VERSION_MAJOR

Relevant
for PCK
Yes

Acknowledgment Messages

XI message protocol version. Example: For the XI


3.0 message protocol VERSION_MAJOR = 3 and
VERSION_MINOR = 0.

VERSION_MINOR

No.
The PCK only
supports
message
protocol XI 3.0.
No

PROCESSING_MODE

The mode of a message can be synchronous or


asynchronous. Correspondingly, these constants
can have the value synchronous or asynchronous.

Yes

MESSAGE_ID

The message ID. It can change during


communication:

Yes

Response messages get a new message ID.

If new messages result from a message


(the message is copied at multiple
receivers), the new messages get new
message IDs.

REF_TO_MESSAGE_ID

The ID of a referenced message that belongs


semantically to this message. For example, a
response message uses this field to note which
request message it belongs to.

Yes

CONVERSATION_ID

This field is not mandatory in the message. It


enables an ID to be used to group messages that
belong together. This field is not intended to be
used for message serialization and has nothing to
do with the serialization context (ABAP proxy
runtime, Java proxy runtime).

Yes

TIME_SENT

Time stamp specifying when the message was sent


by the sender. The format of the time stamp is as
follows:

Yes

YYYY-MM-DDTHH:MM:SSZ
The letter T separates the date from the
time, which is generally specified in UTC. If it is a
local time, the closing Z is omitted.

Reference: Java Mapping V1.0.doc

Page 5 of 40

Training Courseware

Java Mapping

INTERFACE

Sender interface name. As of SAP XI 3.0, use this


constant instead of the constant SENDER_NAME
used previously.

Yes

INTERFACE_NAMESPACE

Sender interface namespace.

Yes

As of SAP XI 3.0, use this constant instead of


the constant SENDER_NAMESPACE used previously.
SENDER_PARTY

Communication party that sent the message.

Yes

SENDER_PARTY_AGENCY

Issuing agency for the message sender.

Yes

SENDER_PARTY_SCHEME

Identification scheme used by the sender.

Yes

SENDER_SERVICE

Service on the sender side that sent the message.


For example, the name of a business system.

Yes

As of SAP XI 3.0, use this constant instead of


the constant SENDER_SYSTEM used previously.
RECEIVER_NAME

Receiver interface name.

Yes

RECEIVER_NAMESPACE

Receiver interface namespace.

Yes

RECEIVER_PARTY

Communication party to receive the message.

Yes

RECEIVER_PARTY_AGENCY

Issuing agency for the message receiver.

Yes

RECEIVER_PARTY_SCHEME

Identification scheme used by the receiver.

Yes

RECEIVER_SERVICE

Service on the receiver side that receives the


message. For example, the name of a business
system.

Yes

As of SAP XI 3.0, use this constant instead of


the constant RECEIVER_SYSTEM used previously.
MAPPING_TRACE

3.2

Returns a MappingTrace object that you can use to


write messages in the monitoring.

No

SAX Parser

The Simple API for XML or SAX is faster and more efficient than using the
DOM. SAX is a Java based API that is very robust and effective. These SAX
parsers make it easy for you to start using the Simple API for XML.
SAX parser is an Event Driven Parser. You provide the callback or handler
methods, and the parser invokes them as it reads the XML data. Finally, you can't
"back up" to an earlier part of the document, or rearrange it, any more than you
can back up a serial data stream or rearrange characters you have read from that
stream. The following Packages need to be imported in your Java File to use the
SAX parser.
import
import
import
import

java.io.*;
org.xml.sax.*;
javax.xml.parsers.SAXParserFactory;
javax.xml.parsers.SAXParser;

public class JSAXMapping extends DefaultHandler


{
...
}

To setup the Parser, following steps are to be carried out.


Reference: Java Mapping V1.0.doc

Page 6 of 40

Training Courseware

Java Mapping

DefaultHandler handler = this;


SAXParserFactory factory = SAXParserFactory.newInstance();
try {
out = new OutputStreamWriter (System.out, "UTF8");
SAXParser saxParser = factory.newSAXParser();
saxParser.parse(in, handler);
} catch (Throwable t) {
t.printStackTrace ();
}

As seen above first we get a new instance of SAXParserFactory and


from this one we create a new Instance of SaxParser. To the Parse Method of
SaxParser, we pass two parameters, InputStream containing the XML File and the
current
object
of
class
JSAXMapping
which
implements
interface
DefaultHandler.
The Following Methods needs to be implemented from the
DocumentHandlerBase Interface, and Description above each method explains
when these Methods are called. These Methods are called automatically while
parsing the XML file and when the corresponding data element is reached. When
you run this Program the output will clearly show when an attribute is reached
and when an Element is reached and how each of these methods is called.
Called when the Parser starts parsing the Current XML File.
public void startDocument () throws SAXException
{
......
}

Called when the Parser completes parsing the Current XML File.
public void endDocument () throws SAXException
{
......
}

Called when the starting of the Element is reached. For Example if we have Tag
called <Title> ... </Title>, then this method is called when <Title> tag is
encountered while parsing the Current XML File. The AttributeList Parameter
has the list of all Attributes declared for the Current Element in the XML File.
public void startElement (String name, AttributeList attrs) throws SAXException
{
......
}

Called when the Ending of the current Element is reached. For example in the
above explanation, this method is called when </Title> tag is reached.
public void endElement (String name) throws SAXException
{
......

Reference: Java Mapping V1.0.doc

Page 7 of 40

Training Courseware

Java Mapping

While Parsing the XML file, if extra characters like space or enter Character are
encountered then this method is called. If you don't want to do anything special
with these characters, then you can normally leave this method blank.
public void characters (char buf [], int offset, int len) throws SAXException
{
......
}

In the XML File if the parser encounters a Processing Instruction which is declared
like this <?ProgramName:ItemList QUERY="Descr, Type, Cost"?> then this
method is called where Target parameter will have "ProgramName:ItemList" and
data parameter will have QUERY=" Descr, Type, Cost". You can invoke an
external
Program
from
this
Method
if
required.
public void processingInstruction (String target, String data) throws SAXException
{
.......
}

3.3

DOM Parser

The Document Object Model (DOM) defines a standard way for accessing
and manipulating XML documents. It presents an XML document as a tree
structure, and gives access to the structure through a set of objects.
To use the DOM parser following packages need to be imported.
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import
import
import
import

org.w3c.dom.Document;
org.w3c.dom.Element;
org.w3c.dom.Node;
org.w3c.dom.NodeList;

To parse the document, following steps are to be carried out.


try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
doc = db.parse(in);
} catch (Exception e) {
e.printStackTrace();
}

DOM parser internally uses SAX parser hence the method parse(in)
throws SAXExecption and therefore the above code has to be put in a try block.
In DOM parser the entire XML is loaded into the memory and consumes a
lot of resources and hence it is processor intensive. After the document gets
loaded it is maintained as a tree structure.

Reference: Java Mapping V1.0.doc

Page 8 of 40

Java Mapping

Training Courseware

Consider the following XML data.

The tree structure for the above XML would be,


MTO_INPUT_BBNU

Item
(Length=4)

Descr

Base
unit

Item
(Length=5)

Cost

Mat_Descr

Type

Descr

Cost

Mat_Descr

Type

950

Telephone
set

Giftset

Alarm
Clock

350

Clock

Single

ELEMENT NODE

TEXT NODE

Reference: Java Mapping V1.0.doc

\n
Newline
character

Page 9 of 40

Java Mapping

Training Courseware

Since the 1st <Item> includes 4 elements under it i.e. <Descr>, <Cost>,
<Mat_Descr> and <Type> hence its length is 4 and length of each of the child
elements under <Item> is 1. It can also be possible that the length of <Item>
element be greater than 4 even if it has only 4 tags present under it. This is
because while parsing the document it also counts the newline characters or
blank spaces as a Node of type TEXT, hence the length of the 2nd <Item> is 5.
Some common set of objects which are used to access the tree structure
are given below.

org.w3c.dom.Document
The Document object represents the entire XML document. It is
the root-node of a document and provides the primary access to the
document's data. All nodes in a node-tree are childnodes of the
Document object.
A node can be an element node, an attribute node, a text node,
or any other of the node types explained in the "org.w3c.dom.Node"
section.

org.w3c.dom.Element
The Element object represents an element in an XML document.
If an element contains text, the text is represented in a text-node.
Element object can be used directly to retrieve either an Attr
object (Attribute) by name or an attribute value by name.

org.w3c.dom.Node
The Node object represents a node in the node-tree. A node
can be an element node, an attribute node, a text node, or any other
of the node types explained.
The following table lists the different node types, and which
node types they may have as children
Node type

Description

Children

Document

Represents the entire document


(it is the root-node of the DOM
tree)

Element (max. one),


ProcessingInstruction,
Comment,
DocumentType

DocumentFragment

Represents
a
"lightweight"
Document object, which can
hold a portion of a document

Element,
ProcessingInstruction,
Comment, Text,
CDATASection,
EntityReference

DocumentType

Represents a list of the entities


that
are
defined
for
the
document

None

Reference: Java Mapping V1.0.doc

Page 10 of 40

Java Mapping

Training Courseware

EntityReference

Represents an entity reference

Element,
ProcessingInstruction,
Comment, Text,
CDATASection,
EntityReference

Element

Represents an element

Element, Text,
Comment,
ProcessingInstruction,
CDATASection,
EntityReference

Attr

Represents an attribute

Text, EntityReference

ProcessingInstruction

Represents
instruction"

None

Comment

Represents a comment

None

Text

Represents
textual
content
(character data) in an element
or attribute

None

CDATASection

Represents a block of text that


may contains characters that
would otherwise be treated as
markup

None

Entity

Represents an entity

Element,
ProcessingInstruction,
Comment, Text,
CDATASection,
EntityReference

Notation

Represents a notation declared


in the DTD

None

"processing

org.w3c.dom.NodeList
The NodeList object represents a node and its child-nodes as a
node-tree.
A node can be an element node, an attribute node, a text node,
or any other node types.

4.0

When to use Java mapping in XI?

Reference: Java Mapping V1.0.doc

Page 11 of 40

Training Courseware

Java Mapping

XI provides 4 standard ways of interface mapping between source and


target.

4.1

Graphical mapping
Java mapping
XSLT mapping
ABAP mapping

How is JAVA mapping different from Graphical, XSLT and ABAP


mapping?

Graphical mapping is an easiest and common approach followed by


everyone for generating desired target structure. It involves simple drag-n-drop
to correlate respective nodes (fields) from source and target structure. It may
involve Java UDFs as a part of the mapping program. But sometimes with
graphical mapping it is difficult or it may seem impossible to produce required
output; for example text/html output, namespace change, sorting or grouping
of records etc. A person comfortable with Object Oriented ABAP can go for ABAP
mapping instead. One can also think of XSLT mapping as another option. In such
cases, when java mapping is used the developer has full control over the
message content and could manipulate it based on the output requirement.
Hence, java mapping can prove to be an efficient approach.
A few example cases in which Java mapping can be used:-

4.2

When the required output is other than XML like Text, Html or XHTML
(html displayed as XML).

When the data is to be extracted from input which is in text format.

When default namespace coming from graphical mapping is not


required or is to be changed as per requirements.

When data is to be filtered, sorted or grouped based on certain fields


(considering File as source)

Advantages of using Java mapping

Java program itself defines its own target structure.

File content conversion at sender side can be avoided in case of text or


html input.

File content conversion at receiver side can be avoided in case of text


or html output.

Java can be used in combination with graphical mapping.

Multi-mapping is also possible using Java mapping.

Reference: Java Mapping V1.0.doc

Page 12 of 40

Training Courseware

4.3

5.0

Java Mapping

Disadvantages of using Java mapping

Once the java mapping has been imported into XI, to incorporate any
further changes one has to compile the java program and import the
class file again into XI.

Resultant XML payload can not be viewed in SXMB_MONI if not in XML


format (for service packs < SP14).

SAP NetWeaver Developer Studio and Tools


Java program can be written in any text editor like Notepad. There are
other editors available like Editplus, JDeveloper, etc. The editor which we are
going to use is SAP NetWeaver Developer Studio which is SAPs Eclipse-based
development environment for Java applications (Standalone or Enterprise
applications), Web Dynpro applications and Web services.
NWDS provides number of perspectives wherein you could create different
types of applications (such as Web Dynpro or Java applications). We would be
using Java perspective to create a mapping program which would be imported for
use in XI.
To do Java developments in NWDS open the Java Perspective Window and
carry out following steps.

To start, first create a Java Project.

Next create a Package within that Project using File > New > Package (use
the Browse... button to select your project if it is not already listed in
Source Folder field).

Reference: Java Mapping V1.0.doc

Page 13 of 40

Training Courseware

Java Mapping

To create a Java class, use the Java Class wizard File > New > Class
(again use the Browse... buttons within the wizard to select the
appropriate Project and Package for your class).

Before we could start the development we have to import an external JAR


file aii_map_api.jar into our Java project. This jar file is available on the
application server at the specified path.
<SID>\DVEBMGS<instance
number>\j2ee\cluster\server\services\deploy\work\applications\Exchange
Repository.
The jar file is attached below.

aii_map_api.jar

To import an external jar file, go to the project properties > Java Build
Path > Libraries > Add External Jars

Reference: Java Mapping V1.0.doc

Page 14 of 40

Training Courseware

Java Mapping

To run any Java program, click on Run > Run.... Select Java Application as
the launch configuration and click New. Identify the program in the Project
and Class fields and then click Run.

NOTE: We are creating the main function only for testing the mapping
program in NWDS. Once it runs through successfully, remove the main
function and the constructor associated with that class before importing it
into XI.
6.0

Steps for implementing Java mapping in XI

Reference: Java Mapping V1.0.doc

Page 15 of 40

Training Courseware

Java Mapping

Java mapping can be defined in XI using very simple steps


1. The first step to writing a java mapping is to be familiar with the XML to be
transformed. So the source data type which needs to be mapped is to be
studied and understood.

2. The next step is to identify the output structure which is to be mapped with
the source XML.
3. We then need to design a java program for mapping the source to target
structures using various classes and interfaces available.

Reference: Java Mapping V1.0.doc

Page 16 of 40

Training Courseware

Java Mapping

4. Message Mapping is not needed to be defined in case of java mapping. The


java mapping program generated in the step above needs to be imported into
XI under the Imported Archives section. To import it, the mapping program
needs to be compressed into a .jar file. In the imported archive section .ZIP
and .JAR files only can be imported.

Reference: Java Mapping V1.0.doc

Page 17 of 40

Training Courseware

Reference: Java Mapping V1.0.doc

Java Mapping

Page 18 of 40

Training Courseware

Java Mapping

5. The next step is to define the Interface Mapping. The Source and Target
Message Interfaces are read. The mapping type is selected as java class and
the imported java class is selected as the mapping program to be used for the
transformation.

Reference: Java Mapping V1.0.doc

Page 19 of 40

Training Courseware

Reference: Java Mapping V1.0.doc

Java Mapping

Page 20 of 40

Training Courseware

7.0

Java Mapping

Examples
In Graphical Mapping, the parsing of source structure is handled internally
by XI. But, when you go for an explicit mapping technique like Java Mapping, you
have to parse the source XML structure, so that you can write the logic for your
mapping.
When the mapping class is executed, a method execute() is called, that
will take the source XML structure as the InputStream which has to be parsed
using SAX or DOM parser.
All the examples would be implemented within a File-to-File scenario.
7.1

Example 1 XML to XML (Using SAX Parser)

This program illustrates a simple mapping where the source message is


same as the target message and only the root node of the message is to be
changed.
The mapping program has been described along with the source and
target messages given below.

Source message:

Reference: Java Mapping V1.0.doc

Page 21 of 40

Training Courseware

Java Mapping

Target message:

The purpose of this class is to have a reference to the OutputStream


(contains message to the inbound side) which could be accessed
directly throughout the mapping program.
class Echo{
public static OutputStream out;
}

This method is required, but we dont do anything here other than


assigning the param variable to map. It can be used to access the
possible runtime constants which are explained in section 3.1.
public void setParameter(Map param) {
map = param;
}

This method is called when parsing of the XML file begins.


Simultaneously it writes a processing instruction into the
OutputStream which specifies the version and encoding style.
public void startDocument() throws SAXException {
try {
Echo.out.write("<?xml version='1.0' encoding='UTF-8'?>".getBytes());

Reference: Java Mapping V1.0.doc

Page 22 of 40

Training Courseware

Java Mapping

}
catch (IOException e) {
e.notify();
}
}

This method is called when parsing of the XML file ends.


public void endDocument() throws SAXException {
try {
Echo.out.flush();
}
catch (IOException e) {
throw new SAXException("I/O error", e);
}
}

This method will read the starting tag in the XML stream and writes it
back into the OutputStream as it is, except for the tag
MTO_SAP_MAT_DETAILS, which is replaced by MTI_FTP_MAT_DETAILS
in the output.
public void startElement(String namespaceURI, String sName, // simple name
String qName, // qualified name
Attributes attrs) throws SAXException {
String eName = sName; // element name
if ("".equals(eName))
eName = qName; // not namespace-aware
if ("ns0:MTO_SAP_MAT_DETAILS".equals(qName)){
try{
Echo.out.write (("<MTI_FTP_MAT_DETAILS>").getBytes());
}
catch(IOException e)
{
e.printStackTrace();
}
}
else{
try{
Echo.out.write (("<"+qName+">").getBytes());
}
catch(Exception e)
{
e.printStackTrace();
}
}
}

This method will read the ending tag in the XML stream and writes it
back into the OutputStream as it is, except for the tag
MTO_SAP_MAT_DETAILS.
public void endElement(String namespaceURI, String sName, // simple name
String qName // qualified name
) throws SAXException {
String eName = sName; // element name
if ("".equals(eName))
eName = qName; // not namespace-aware
if ("ns0:MTO_SAP_MAT_DETAILS".equals(qName)){
try{

Reference: Java Mapping V1.0.doc

Page 23 of 40

Training Courseware

Java Mapping

Echo.out.write (("</MTI_FTP_MAT_DETAILS>").getBytes());
}
catch(Exception e)
{
e.printStackTrace();
}
}
else{

try{
Echo.out.write (("</"+qName+">").getBytes());
}
catch(Exception e)
{
e.printStackTrace();
}

This would copy the characters between the start and end tags of an
element into OutputStream.
public void characters(char buf[], int offset, int len)
throws SAXException {
String s = new String(buf, offset, len);
try{
Echo.out.write (s.getBytes());
}
catch(Exception e)
{
e.printStackTrace();
}
}

The complete java program is given below.

Package

7.2

Example 2 XML to XML (Using SAX Parser)

This program which is similar to that of the previous example


demonstrates an enhanced mapping. In SAX parser, after the parsing of the
document has begun, the element which has already been parsed and processed
cant be reprocessed again i.e. it cant go back to that element again. Hence to
access the contents of the elements again temporary variables have been used.
The description of the mapping program is given below along with the
source and target messages.

Source message:

Reference: Java Mapping V1.0.doc

Page 24 of 40

Training Courseware

Java Mapping

Target message:
The target requirement is to categorize all the items from the
source message based on the material description and the type of
material.
For e.g; Cordless and Base Unit belongs to a Telephone set.

Reference: Java Mapping V1.0.doc

Page 25 of 40

Java Mapping

Training Courseware

The purpose of this class is to have a reference to the OutputStream


(contains message to the inbound side) which could be accessed
directly throughout the mapping program.
class Echo{
public static OutputStream out;
}

The object of class Material would be used to hold the data retrieved
from the InputStream. If there are multiple items belonging to the
same category then the description and cost of all those items would
be stored in the vectors Descr and Cost.
class Material {
Vector Descr;
Vector Cost;
String TotalCost;
String MatDescr;
String Type;
}

Repeats for each


item with same
MatDescr & Type

Each object of this class represents a material which may contain a


list of items or a single item.

This method is called as soon as the mapping is triggered.


public void execute(InputStream in, OutputStream out) {
DefaultHandler handler = this;
SAXParserFactory factory = SAXParserFactory.newInstance();
try {
SAXParser saxParser = factory.newSAXParser();
Echo.out = out;
saxParser.parse(in, handler);
Echo.out.write("<MTI_OUTPUT>".getBytes());
for (int i = 0; i < ItemNo; i++) {
M[i].display();
}
Echo.out.write("</MTI_OUTPUT>".getBytes());
} catch (Throwable t) {
t.printStackTrace();
}
}

After the parsing of the document is completed, display() method


is called which would output the extracted data in an XML format into
the OutputStream.

This method is required, but we dont do anything here other than


assigning the param variable to map. It can be used to access the
possible runtime constants which are explained in section 3.1.
public void setParameter(Map param) {
map = param;
}

Reference: Java Mapping V1.0.doc

Page 26 of 40

Training Courseware

Java Mapping

This method is called when parsing of the XML file begins.


Simultaneously it writes a processing instruction into the
OutputStream which specifies the version and encoding style.
public void startDocument() throws SAXException {
try {
Echo.out.write("<?xml version='1.0' encoding='UTF-8'?>".getBytes());
}
catch (IOException e) {
e.notify();
}
}

This method is called when parsing of the XML file ends.


public void endDocument() throws SAXException {
try {
Echo.out.flush();
}
catch (IOException e) {
throw new SAXException("I/O error", e);
}
}

This method will read the starting tag (element) in the XML stream
and sets the appropriate flag which would be used later to determine
which element is getting processed currently.
public void startElement(String namespaceURI, String sName, // simple name
String qName, // qualified name
Attributes attrs) throws SAXException {
String eName = sName; // element name
if ("".equals(eName))
eName = qName; // not namespace-aware
if (eName.equals("Item")) {
ItemF = 1;
}
if (eName.equals("Descr")) {
DescrF = 1;
}
if (eName.equals("Cost")) {
CostF = 1;
}
if (eName.equals("Type")) {
TypeF = 1;
}
if (eName.equals("Mat_Descr")) {
MatDescrF = 1;
}

This method will reset the flag variables specifying the completion of
processing of an element i.e. whenever an end tag is encountered the
flag referring to that particular tag is reset.
When the Item end tag is encountered, since the item tag
encapsulates all the details of an item, it identifies that the processing
of all the details of that particular item is complete. Once the item is

Reference: Java Mapping V1.0.doc

Page 27 of 40

Training Courseware

Java Mapping

extracted the details like material description and type is compared


with already processed items, if the material description and type
already exits then the new item is appended into that material.
public void endElement(String namespaceURI, String sName, // simple name
String qName // qualified name
) throws SAXException {
String eName = sName; // element name
if ("".equals(eName))
eName = qName; // not namespace-aware
if (eName.equals("Item")) {
ItemNo = ItemNo + 1;
ItemF = 0;
int f = 0;
for (int j = 0; j < ItemNo - 1; j++) {
if (M[j] != null)
if (M[j].MatDescr.equals(MTemp.MatDescr) && M[j].Type.equals(MTemp.Type))
{
for (int i = 0; i < MTemp.Descr.size(); i++) {
M[j].Descr.addElement(MTemp.Descr.get(i));
M[j].Cost.addElement(MTemp.Cost.get(i));
int TC = Integer.parseInt(M[j].TotalCost)+ Integer.parseInt((String)
MTemp.Cost.get(i));
M[j].TotalCost = Integer.toString(TC);
}
f = 1;
ItemNo = ItemNo - 1;
break;
}
}
if (f == 0)
M[ItemNo - 1] = new Material(MTemp);
}
if (eName.equals("Descr")) {
DescrF = 0;
}
if (eName.equals("Cost")) {
CostF = 0;
}
if (eName.equals("Mat_Descr")) {
MatDescrF = 0;
}
if (eName.equals("Type")) {
TypeF = 0;
}
}

The flag variables which were set in startElement() method would be


checked in this method to determine which element is being processed
and the value of that element would be taken into a respective
variable.
public void characters(char buf[], int offset, int len)
throws SAXException {
String s = new String(buf, offset, len);
if (ItemF == 1 && DescrF == 1) {
MTemp.Descr.removeAllElements();
MTemp.Descr.addElement(s);
MTemp.ItmNo = 1;
}
if (ItemF == 1 && CostF == 1) {

Reference: Java Mapping V1.0.doc

Page 28 of 40

Training Courseware

Java Mapping

MTemp.Cost.removeAllElements();
MTemp.Cost.addElement(s);
MTemp.TotalCost = new String(s);

}
if (ItemF == 1 && MatDescrF == 1) {
MTemp.MatDescr = s;
}
if (ItemF == 1 && TypeF == 1) {
MTemp.Type = s;
}
}

The complete java program is given below.

Package

7.3

Example 3 XML to XML (Using DOM Parser)

This is a simple mapping program which demonstrates the usage of DOM


parser. Here the source message is same as the target message.
The mapping program has been described along with the source and
target messages given below.

Source message:

Target message:

Reference: Java Mapping V1.0.doc

Page 29 of 40

Training Courseware

Java Mapping

The purpose of this class is to have a reference to the OutputStream


(contains message to the inbound side) which could be accessed
directly throughout the mapping program.
class OPF {
public static OutputStream out;
}

This method is required, but we dont do anything here other than


assigning the param variable to map. It can be used to access the
possible runtime constants which are explained in section 3.1.
public void setParameter(Map param) {
map = param;
}

The flowchart below would describe the entire program execution.

Reference: Java Mapping V1.0.doc

Page 30 of 40

Java Mapping

Training Courseware

Start of
execute(in,

out)
Write start tag
<MTI_OUTPUT>
into the
OutputStream

Parse the Document and


get the root element.

End of
execute(in, out)

Get 1st child of the root


element

Is Child !=
Null?

Write end tag


</MTI_OUTPUT>
into the
OutputStream
No

Yes

Type of
Child =
Text?
Yes
Write the node
value into the
OutputStream

No

Type of
Child =
Element?
Yes

No

Call function
getnodes(Child)

Get next child of the root


element

Reference: Java Mapping V1.0.doc

Page 31 of 40

Java Mapping

Training Courseware

Start of
getnodes(child)

Write start tag


of the node
into
OutputStream

Return

Get 1st child of the


element node

Is Child !=
Null?

Write end tag


of the node
into
OutputStream
No

Yes

Type of
Child =
Text?
Yes
Write the node
value into the
OutputStream

No

Type of
Child =
Element?
Yes

No

Call function
getnodes(Child)

Get next child of the


element node

In the execute method the root element in the XML document is


retrieved and it is checked for any existence of the child elements
under it. If there is only one child element which is of type TEXT then
it writes the node value into the OutputStream. If the child is of type
ELEMENT then it calls the method getnodes(Child) which would
consider that child element as the root node and again it would repeat
the same process.
public void execute(InputStream in, OutputStream out) {

Reference: Java Mapping V1.0.doc

Page 32 of 40

Training Courseware

Java Mapping

Document doc = null;


try {
OPF.out = out;
OPF.out.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>".getBytes());
OPF.out.write("<MTI_OUTPUT>".getBytes());
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
doc = db.parse(in);
} catch (Exception e) {
e.printStackTrace();
}
Element root = doc.getDocumentElement();
for (Node child = root.getFirstChild();
child != null;
child = child.getNextSibling()) {
if (child.getNodeType() == Node.TEXT_NODE)
try {
OPF.out.write((child.getNodeValue()).getBytes());
} catch (IOException e) {
e.printStackTrace();
} else if (child.getNodeType() == Node.ELEMENT_NODE)
if (child.getChildNodes() != null)
getnodes(child);
}
try {
OPF.out.write("</MTI_OUTPUT>".getBytes());
} catch (Exception e) {
e.printStackTrace();
}

This is a recursive method which retrieves the nested elements from


the document. For each and every node in the document which is of
type ELEMENT this function is called.
public void getnodes(Node Child, StringBuffer sbf) {
NodeList children = Child.getChildNodes();
if (children.getLength() > 0) {
try {
OPFile.out.write(("<" + Child.getNodeName() + ">").getBytes());
}
catch (IOException ex) {
}
}
for (Node child = Child.getFirstChild(); child != null; child =
child.getNextSibling()) {
if (child.getNodeType() == Node.TEXT_NODE)
sbf.append((child.getNodeValue()).trim());
else if (child.getNodeType() == Node.ELEMENT_NODE)
if (child.getChildNodes() != null) {
sbf = new StringBuffer();
getnodes(child, sbf);
try {
OPFile.out.write(sbf.toString().getBytes());
OPFile.out.write(("</" + child.getNodeName() + ">").getBytes());
}
catch (IOException ex) {
}
}
}
if (children.getLength() > 1) {
try {
OPFile.out.write(("</" + Child.getNodeName() + ">").getBytes());

Reference: Java Mapping V1.0.doc

Page 33 of 40

Training Courseware

Java Mapping

}
catch (IOException ex) {
}

The complete java program is given below.

Package

7.4

Example 4 XML to Text (Using DOM Parser)

This is a simple mapping program which demonstrates the usage of DOM


parser. Here the source message which is in XML format is transformed into a
text document.
This program uses a similar set of objects and functions which were used
in the previous example.
The source and target messages are given below.

Source message:

Target message:

Reference: Java Mapping V1.0.doc

Page 34 of 40

Training Courseware

Java Mapping

The complete java program is given below.

Package

7.5

Example 5 XML to HTML (Using SAX Parser)

This scenario is similar to Example 2 except that output is now HTML


format instead of XML file.

Source message:

Reference: Java Mapping V1.0.doc

Page 35 of 40

Training Courseware

Java Mapping

Target message:

The complete java program is given below.

Package

7.6

Example 6 Text to XML

Reference: Java Mapping V1.0.doc

Page 36 of 40

Training Courseware

Java Mapping

This is a simple example which deals with the transformation of comma


delimited text file into XML file.

Source message:

Target message:

Since the source document is in text format we wont require a parser


to retrieve the data from the InputStream. The data in the
InputStream is still in raw format. To restructure the data we need to
the read it using a Reader object.
BufferedReader bin = new BufferedReader(new InputStreamReader(in));

This would create a BufferedReader object which would buffer the


input from the InputStream.

Reference: Java Mapping V1.0.doc

Page 37 of 40

Training Courseware

Java Mapping

The buffered input can be read line by line or even by characters. The
file which we are processing is a comma delimited file and the data
within a line read can be extracted easily using the delimiter.
The following code demonstrates how the Item and Cost within
each line of the file is read.
while ((line = bin.readLine()) != null) {
String Item = line.substring(0, line.indexOf(","));
String Cost = new String( line.toCharArray(),
line.indexOf(",") + 1,
line.length() - Item.length() - 1);

out.write(("<Item>" + Item + "</Item>").getBytes());


out.write(("<Cost>" + Cost + "</Cost>").getBytes());

This is as good as a content conversion which is done at the


sender communication channel.
The complete source code is given below.

Package

8.0

When to use SAX and DOM parsers?

The choice between DOM and SAX depends on several factors like Size of XML
Document, Speed, Memory Resources, Navigation and some times ease of programming
too.

Memory considerations

DOM creates an in-memory representation of the whole document where


as SAX does not require the whole document to be in memory. Because of this
DOM requires more memory resources and is not recommended when the
document size is big.

Ease of Programming

As the name implies SAX is a very simple solution to process the XML
Documents but puts the burden on the programmer. This is because in SAX the
programmer has to create his own object model and write code that respond to
the SAX events. Whereas incase of DOM, it creates the object model and gives a
reference to the object model. We can make use of DOM with less code but we
got to do lot of work to use SAX.

Reference: Java Mapping V1.0.doc

Page 38 of 40

Training Courseware

Java Mapping

Efficiency

SAX is more efficient than DOM when the object model that is built upon
on SAX by the programmer is simple. This is because SAX does less work than
DOM and can be really fast at runtime.

Navigation

Random Navigation is available in DOM as the tree model is in memory all


the time i.e. any element or node from a XML document can be accessed at any
time. On the other hand, SAX processes the XML Document sequentially and so
backward navigation is not possible. This is considered as a major disadvantage
of SAX. The only work around is to store this information by writing extra code. If
we do so, that results in memory overhead and defeats the purpose of using SAX.

Some scenarios

We take a few real time scenarios and analyze the appropriate use of SAX
and DOM.
1. Consider that a news agency Application has an XML Document that
holds the national, International and local news information. The users
of that news agency frequently search within that document structure
to find required information. Assuming that there are no memory
constrains, which one of the two (DOM, SAX) has to be used for paring
the XML Document by the application? As the Application needs to do
frequent search, DOM is considered the best solution. This is because
DOM creates a tree-based representation in memory and this tree
object model is very useful for frequent access or search. The only
disadvantage of DOM is that it consumes more memory resources. As
there are no memory constraints in this case, DOM is the best choice.
2. Consider that we need to extract only a subset of information that is
present in a large Size XML Document. Which is the best way to do it?
Event based API is the best choice to do it. This is because SAX
Processes the XML Documents sequentially and so it does not have to
process the whole document to extract the required information. On
the other hand, DOM creates a tree based in memory representation of
the whole document. Document size being large in this case, this
consumes lot of memory resources and is not the right choice.
3. Consider that XML documents of document management system
contain document data, application data, scripts or other code within
the document. These applications and scripts explore and edit the
document content. Which is the best way to process such XML
Documents? DOM is the best way to do process these types of XML
Documents. This is because DOM allows programs to access and edit
the information stored in these documents. On the other hand, SAX
can only deal with structured data.
9.0

References

Reference: Java Mapping V1.0.doc

Page 39 of 40

Training Courseware

Java Mapping

i) Links
(a) JAXP APIs for XML
http://java.sun.com/j2se/1.5.0/docs/api/javax/xml/parsers/packagesummary.html
(b) Using the SAX and DOM APIs
http://java.sun.com/developer/TechTips/2000/tt0627.html
(c) XML DOM Tutorial
http://www.w3schools.com/dom/default.asp
(d) DOM Vs SAX
http://www.code101.com/Code101/DisplayArticle.aspx?cid=37
ii) SDN Weblogs/SAP help
(a) Java Mapping
http://help.sap.com/saphelp_nw04/helpdata/en/14/80243b4a66ae0ce
10000000a11402f/frameset.htm
(b) SAX Parser weblog
https://www.sdn.sap.com/irj/sdn/weblogs?blog=/pub/wlg/1817
(c) Java Mapping weblog
https://www.sdn.sap.com/irj/sdn/weblogs?blog=/pub/wlg/1945(Part1)
https://www.sdn.sap.com/irj/sdn/weblogs?blog=/pub/wlg/1946(Part2)
https://www.sdn.sap.com/irj/sdn/weblogs?blog=/pub/wlg/1947(Part3)

Reference: Java Mapping V1.0.doc

Page 40 of 40

S-ar putea să vă placă și