代码语言:javascript复制
REPORT ZXML_A.
SET EXTENDED CHECK OFF.
TYPE-POOLS: IXML.
*&---------------------------------------------------------------------*
*& Report T_DOM_MANIPULATE
*&
*&---------------------------------------------------------------------*
*& shows how to manipulate a dom tree
*&---------------------------------------------------------------------*
***********************************************************
* macros
DEFINE XML.
WRITE: / 'XML:', &1 COLOR COL_POSITIVE INVERSE.
END-OF-DEFINITION.
*************************************************************
* global data
*
DATA: DOCUMENT TYPE REF TO IF_IXML_DOCUMENT,
RET TYPE I.
*************************************************************
* building a DOM tree from scratch
*
START-OF-SELECTION.
* create the tree
PERFORM CREATE_DOM CHANGING DOCUMENT.
* print the tree
ULINE. WRITE: / 'DOCUMENT BEFOR MANIPULATION'.
PERFORM PRINT_DOM USING DOCUMENT.
* render the tree
PERFORM MANIP_DOM CHANGING DOCUMENT.
* print the tree
ULINE. WRITE: / 'DOCUMENT AFTER MANIPULATION'.
PERFORM PRINT_DOM USING DOCUMENT.
* render the tree
PERFORM RENDER_DOM CHANGING DOCUMENT.
*&---------------------------------------------------------------------*
*& Form create_dom
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* <--P_DOCUMENT text
*----------------------------------------------------------------------*
FORM CREATE_DOM CHANGING DOCUMENT TYPE REF TO IF_IXML_DOCUMENT.
*------------------------------
* document to create
*------------------------------
* <?xml version="1.0"?>
* <order number="4711">
* <head>
* <status>confirmed</status>
* <date format="mm/dd/yyyy">08/15/1999</date>
* </head>
* <body>
* <item pos="10" units="2" price="17">abap-book </item>
* <item pos="20" units="1" price="10">sapr3-cdrom</item>
* <item pos="30" units="5" price="12">coffee </item>
* </body>
* </order>
*------------------------------
DATA: IXML TYPE REF TO IF_IXML,
PARENT TYPE REF TO IF_IXML_NODE,
ELEMENT TYPE REF TO IF_IXML_ELEMENT,
NODE TYPE REF TO IF_IXML_NODE,
RET TYPE I.
* create the ixml main factory
IXML = CL_IXML=>CREATE( ).
* create a empty document
DOCUMENT = IXML->CREATE_DOCUMENT( ).
* create root node <order> "根节点!!!!!!!!!!
ELEMENT = DOCUMENT->CREATE_ELEMENT( NAME = 'order' ).
RET = ELEMENT->SET_ATTRIBUTE( NAME = 'number' VALUE = '4711' ).
RET = DOCUMENT->APPEND_CHILD( NEW_CHILD = ELEMENT ).
* remember <order> node
PARENT = ELEMENT.
* create node <head>
ELEMENT = DOCUMENT->CREATE_ELEMENT( NAME = 'head' ).
RET = PARENT->APPEND_CHILD( NEW_CHILD = ELEMENT ).
* create node <body>
ELEMENT = DOCUMENT->CREATE_ELEMENT( NAME = 'body' ).
RET = PARENT->APPEND_CHILD( NEW_CHILD = ELEMENT ).
* find <head> node
PARENT = DOCUMENT->FIND_FROM_NAME( NAME = 'head' ).
* create <status>confirmed</status>
ELEMENT = DOCUMENT->CREATE_ELEMENT( NAME = 'status' ).
RET = ELEMENT->SET_VALUE( VALUE = 'confirmed' ).
RET = PARENT->APPEND_CHILD( NEW_CHILD = ELEMENT ).
* create <date format="mm/dd/yyyy">08/15/2001</date>
ELEMENT = DOCUMENT->CREATE_ELEMENT( NAME = 'date' ).
RET = ELEMENT->SET_ATTRIBUTE( NAME = 'format' VALUE = 'mm/dd/yyyy' ).
RET = ELEMENT->SET_VALUE( VALUE = '08/15/2001' ).
RET = PARENT->APPEND_CHILD( NEW_CHILD = ELEMENT ).
* find <body> node
PARENT = DOCUMENT->FIND_FROM_NAME( NAME = 'body' ).
* create <item pos="10" units="2" price="17">abap-book</item>
ELEMENT = DOCUMENT->CREATE_ELEMENT( NAME = 'item' ).
RET = ELEMENT->SET_ATTRIBUTE( NAME = 'pos' VALUE = '10' ).
RET = ELEMENT->SET_ATTRIBUTE( NAME = 'units' VALUE = '2' ).
RET = ELEMENT->SET_ATTRIBUTE( NAME = 'price' VALUE = '17' ).
RET = ELEMENT->SET_ATTRIBUTE( NAME = 'st' VALUE = '1' ).
RET = ELEMENT->SET_VALUE( VALUE = 'abap-book' ).
RET = PARENT->APPEND_CHILD( NEW_CHILD = ELEMENT ).
* create <item pos="20" units="1" price="10">sapr3-cdrom</item>
ELEMENT = DOCUMENT->CREATE_ELEMENT( NAME = 'item' ).
RET = ELEMENT->SET_ATTRIBUTE( NAME = 'pos' VALUE = '20' ).
RET = ELEMENT->SET_ATTRIBUTE( NAME = 'units' VALUE = '1' ).
RET = ELEMENT->SET_ATTRIBUTE( NAME = 'price' VALUE = '10' ).
RET = ELEMENT->SET_ATTRIBUTE( NAME = 'st' VALUE = '2' ).
RET = ELEMENT->SET_VALUE( VALUE = 'sapr3-cdrom' ).
RET = PARENT->APPEND_CHILD( NEW_CHILD = ELEMENT ).
* create <item pos="30" units="5" price="12">coffee</item>
ELEMENT = DOCUMENT->CREATE_ELEMENT( NAME = 'item' ).
RET = ELEMENT->SET_ATTRIBUTE( NAME = 'pos' VALUE = '30' ).
RET = ELEMENT->SET_ATTRIBUTE( NAME = 'units' VALUE = '5' ).
RET = ELEMENT->SET_ATTRIBUTE( NAME = 'price' VALUE = '10' ).
RET = ELEMENT->SET_ATTRIBUTE( NAME = 'st' VALUE = '3' ).
RET = ELEMENT->SET_VALUE( VALUE = 'coffee' ).
RET = PARENT->APPEND_CHILD( NEW_CHILD = ELEMENT ).
ENDFORM. " create_dom
*&---------------------------------------------------------------------*
*& Form render_dom
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* <--P_DOCUMENT text
*----------------------------------------------------------------------*
FORM RENDER_DOM CHANGING P_DOCUMENT.
*
* render DOM into a string
*
TYPES: C_LINE(50) TYPE C.
DATA: IXML TYPE REF TO IF_IXML,
RENDERER TYPE REF TO IF_IXML_RENDERER,
STREAMFACTORY TYPE REF TO IF_IXML_STREAM_FACTORY,
OSTREAM TYPE REF TO IF_IXML_OSTREAM,
ENCODING TYPE REF TO IF_IXML_ENCODING,
XMLLINE TYPE C_LINE,
XMLTAB TYPE STANDARD TABLE OF C_LINE,
CHARSET TYPE STRING,
SUCCESS TYPE C.
* create the ixml main factory
IXML = CL_IXML=>CREATE( ).
* create a streamFactory
STREAMFACTORY = IXML->CREATE_STREAM_FACTORY( ).
* create a output stream
OSTREAM = STREAMFACTORY->CREATE_OSTREAM_ITABLE( TABLE = XMLTAB ).
* set an document encoding (optional)
" charsets: utf-8, utf-16, sap*
IF NOT CHARSET IS INITIAL.
ENCODING = IXML->CREATE_ENCODING( CHARACTER_SET = CHARSET
BYTE_ORDER = 0 ).
SUCCESS = OSTREAM->SET_ENCODING( ENCODING = ENCODING ).
ENDIF.
* create a xml renderer
RENDERER = IXML->CREATE_RENDERER( DOCUMENT = DOCUMENT
OSTREAM = OSTREAM ).
* render document into output-stream
IF RENDERER->RENDER( ) <> 0.
* error
WRITE: / 'ERROR: document rendering'.
EXIT.
ENDIF.
* dump xml table
ULINE.
WRITE: /.
WRITE: / ' RENDERED XML-DATA'.
WRITE: /.
LOOP AT XMLTAB INTO XMLLINE.
XML XMLLINE.
ENDLOOP.
ENDFORM. " render_dom
*---------------------------------------------------------------------*
* ORM print_tree *
*---------------------------------------------------------------------*
* ........ *
*---------------------------------------------------------------------*
FORM PRINT_DOM USING DOCUMENT TYPE REF TO IF_IXML_DOCUMENT.
DATA: NODE TYPE REF TO IF_IXML_NODE,
ITERATOR TYPE REF TO IF_IXML_NODE_ITERATOR,
NODEMAP TYPE REF TO IF_IXML_NAMED_NODE_MAP,
ATTR TYPE REF TO IF_IXML_NODE,
NAME TYPE STRING,
PREFIX TYPE STRING,
VALUE TYPE STRING,
INDENT TYPE I,
COUNT TYPE I,
INDEX TYPE I.
CHECK NOT DOCUMENT IS INITIAL.
NODE = DOCUMENT.
ULINE.
WRITE: /.
WRITE: /' DOM-TREE'.
WRITE: /.
IF NODE IS INITIAL. EXIT. ENDIF.
* create a node iterator
ITERATOR = NODE->CREATE_ITERATOR( ).
* get current node
NODE = ITERATOR->GET_NEXT( ).
* loop over all nodes
WHILE NOT NODE IS INITIAL.
INDENT = NODE->GET_HEIGHT( ) * 2.
INDENT = INDENT 20.
CASE NODE->GET_TYPE( ).
WHEN IF_IXML_NODE=>CO_NODE_ELEMENT.
* element node
NAME = NODE->GET_NAME( ).
NODEMAP = NODE->GET_ATTRIBUTES( ).
WRITE: / 'ELEMENT :'.
WRITE: AT INDENT NAME COLOR COL_POSITIVE INVERSE.
IF NOT NODEMAP IS INITIAL.
* attributes
COUNT = NODEMAP->GET_LENGTH( ).
DO COUNT TIMES.
INDEX = SY-INDEX - 1.
ATTR = NODEMAP->GET_ITEM( INDEX ).
NAME = ATTR->GET_NAME( ).
PREFIX = ATTR->GET_NAMESPACE( ).
VALUE = ATTR->GET_VALUE( ).
WRITE: / 'ATTRIBUTE:'.
WRITE: AT INDENT NAME COLOR COL_HEADING INVERSE, '=',
VALUE COLOR COL_TOTAL INVERSE.
ENDDO.
ENDIF.
WHEN IF_IXML_NODE=>CO_NODE_TEXT OR
IF_IXML_NODE=>CO_NODE_CDATA_SECTION.
* text node
VALUE = NODE->GET_VALUE( ).
WRITE: / 'TEXT :'.
WRITE: AT INDENT VALUE COLOR COL_GROUP INVERSE.
ENDCASE.
* advance to next node
NODE = ITERATOR->GET_NEXT( ).
ENDWHILE.
ENDFORM. "traverse_dom
*&---------------------------------------------------------------------*
*& Form display_dom
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* -->P_DOCUMENT text
*----------------------------------------------------------------------*
FORM DISPLAY_DOM USING DOCUMENT TYPE REF TO IF_IXML_DOCUMENT
TITEL LIKE SY-TITLE.
* display document
CALL FUNCTION 'SDIXML_DOM_TO_SCREEN'
EXPORTING
DOCUMENT = DOCUMENT
TITLE = TITEL.
ENDFORM. " display_dom
*&---------------------------------------------------------------------*
*& Form manip_dom
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* <--P_DOCUMENT text
*----------------------------------------------------------------------*
FORM MANIP_DOM CHANGING DOCUMENT TYPE REF TO IF_IXML_DOCUMENT.
*------------------------------
* document now looks like
*------------------------------
* <?xml version="1.0"?>
* <order number="4711">
* <head>
* <status>confirmed</status>
* <date format="mm/dd/yyyy">08/15/1999</date>
* </head>
* <body>
* <item pos="10" units="2" price="17">abap-book </item>
* <item pos="20" units="1" price="10">sapr3-cdrom</item>
* <item pos="30" units="5" price="12">coffee </item>
* </body>
* </order>
*------------------------------
DATA: ORDER TYPE REF TO IF_IXML_ELEMENT,
HEAD TYPE REF TO IF_IXML_ELEMENT,
BODY TYPE REF TO IF_IXML_ELEMENT,
STATUS TYPE REF TO IF_IXML_ELEMENT,
DATE TYPE REF TO IF_IXML_ELEMENT.
* using the method find_from_name
ORDER = DOCUMENT->FIND_FROM_NAME( NAME = 'order' ).
HEAD = DOCUMENT->FIND_FROM_NAME( NAME = 'head' ).
BODY = DOCUMENT->FIND_FROM_NAME( NAME = 'body' ).
STATUS = DOCUMENT->FIND_FROM_NAME( NAME = 'status' ).
DATE = DOCUMENT->FIND_FROM_NAME( NAME = 'date' ).
* update <order>
DATA: OLD TYPE STRING.
OLD = ORDER->GET_ATTRIBUTE( NAME = 'number' )."old = 4711
RET = ORDER->SET_ATTRIBUTE( NAME = '赵博良' VALUE = '001' ). " ret = 0
* update <date>
RET = DATE->SET_ATTRIBUTE( NAME = 'format' VALUE = 'mm-dd-yyyy' ).
RET = DATE->SET_VALUE( VALUE = '12-01-2000' ).
* update <item>
DATA: ITEMS TYPE REF TO IF_IXML_NODE_COLLECTION,
ITEM TYPE REF TO IF_IXML_ELEMENT,
NODE TYPE REF TO IF_IXML_NODE,
VAL TYPE STRING,
IDX TYPE I,
LEN TYPE I.
ITEMS = BODY->GET_ELEMENTS_BY_TAG_NAME( NAME = 'item' ).
LEN = ITEMS->GET_LENGTH( ).
DO LEN TIMES.
* get item
IDX = SY-INDEX - 1.
IF SY-SAPRL >= '610'."gui 的版本???????
* REL >= 6.10: we use simple cast
ITEM ?= ITEMS->GET_ITEM( INDEX = IDX ).
ELSE.
* REL < 6.10: explicit query_interface is required
NODE = ITEMS->GET_ITEM( INDEX = IDX ).
ITEM ?= NODE->QUERY_INTERFACE( IID = IXML_IID_ELEMENT ).
ENDIF.
* change pos
VAL = SY-INDEX.
RET = ITEM->SET_ATTRIBUTE( NAME = 'pos' VALUE = VAL ).
* remove attr st='X'
RET = ITEM->REMOVE_ATTRIBUTE( NAME = 'st' ). "删除了st 节点
* add attr ln='X'
RET = ITEM->SET_ATTRIBUTE( NAME = 'idx' VALUE = VAL ).
ENDDO.
*------------------------------
* document now looks like
*------------------------------
* <?xml version="1.0" ?>
* <order number="4711" type="001">
* <head>
* <status>confirmed</status>
* <date format="mm-dd-yyyy">12-01-2000</date>
* </head>
* <body>
* <item pos="1" units="2" price="17" idx="1">abap-book</item>
* <item pos="2" units="1" price="10" idx="2">sapr3-cdrom</item>
* <item pos="3" units="5" price="10" idx="3">coffee</item>
* </body>
* </order>
*------------------------------
ENDFORM. " manip_dom