Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

xml to internal table

Former Member
0 Kudos
450

Hello all,

I have an xml stored in a string. Its format is as below:

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

......

<QfiData xmlns="http://www2.siemens.nl/qfiservice/QfiData.xsd">

<Material diffgr:id="Material1" msdata:rowOrder="0">

<Material>463581</Material>

<ConditionRate> 2.44</ConditionRate>

<ValidFrom>20060208</ValidFrom>

<ValidTo>99991231</ValidTo>

<RegionID>48</RegionID>

<MaterialID>36294</MaterialID>

</Material>

<Material diffgr:id="Material2" msdata:rowOrder="1">

<Material>463582</Material>

<ConditionRate> 2.44</ConditionRate>

<ValidFrom>20060208</ValidFrom>

<ValidTo>99991231</ValidTo>

<RegionID>48</RegionID>

<MaterialID>36295</MaterialID>

</Material>

.....

Now the question is, i want to read only the child nodes of Material i.e., material, condition rate, validfrom, valid to, regionid, materilid and store these in an internal table.

Can anyone help me.

Thankyou.

1 ACCEPTED SOLUTION

athavanraja
Active Contributor
0 Kudos
280

XLST program code (YSIMPLEXMLTOITAB)

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:strip-space elements="*"/>
  <xsl:output indent="yes"/>
  <xsl:template match="QfiData">
    <asx:abap xmlns:asx="http://www.sap.com/abapxml">
      <asx:values>
        <I_DATA>
          <xsl:for-each select="Materials">
            <I_DATA1>
              <MATERIAL>
                <xsl:value-of select="Material"/>
              </MATERIAL>
              <CONDITIONRATE>
                <xsl:value-of select="ConditionRate"/>
              </CONDITIONRATE>
              <VALIDFROM>
                <xsl:value-of select="ValidFrom"/>
              </VALIDFROM>
              <VALIDTO>
                <xsl:value-of select="ValidTo"/>
              </VALIDTO>
              <REGIONID>
                <xsl:value-of select="RegionID"/>
              </REGIONID>
              <MATERIALID>
                <xsl:value-of select="MaterialID"/>
              </MATERIALID>
            </I_DATA1>
          </xsl:for-each>
        </I_DATA>
      </asx:values>
    </asx:abap>
  </xsl:template>
</xsl:stylesheet>

Program to test it.

REPORT  y_test_xml_tran.

TYPES: BEGIN OF i_det,
Material(10),
ConditionRate(16) type p decimals 2 ,
ValidFrom(10) ,
ValidTo(10) ,
RegionID(3) ,
MaterialID(10) ,
end of i_det .
DATA: i_data TYPE TABLE OF i_det.
data: wa like line of i_data .

DATA: xml_string TYPE string .
DATA: xslt_error	TYPE REF TO	cx_xslt_exception,
xslt_message	TYPE	string .

CLEAR xml_string .
CONCATENATE

`<?xml version="1.0" encoding="utf-8"?>`
`<QfiData xmlns:xsl="http://www2.siemens.nl/qfiservice/QfiData.xsd">`
`<Materials>`
`<Material>463581</Material>`
`<ConditionRate> 2.44</ConditionRate>`
`<ValidFrom>20060208</ValidFrom>`
`<ValidTo>99991231</ValidTo>`
`<RegionID>48</RegionID>`
`<MaterialID>36294</MaterialID>`
`</Materials>`
`<Materials>`
`<Material>463582</Material>`
`<ConditionRate> 2.44</ConditionRate>`
`<ValidFrom>20060208</ValidFrom>`
`<ValidTo>99991231</ValidTo>`
`<RegionID>48</RegionID>`
`<MaterialID>36295</MaterialID>`
`</Materials>`
`</QfiData>`
INTO xml_string .


TRY .
    CALL TRANSFORMATION (`YSIMPLEXMLTOITAB`)
    SOURCE XML  xml_string
    RESULT     i_data = i_data.
  CATCH cx_xslt_exception INTO xslt_error.
    xslt_message = xslt_error->get_text( ).
ENDTRY.

Regards

Raja

22 REPLIES 22

Former Member
0 Kudos
280

Hi Bobby,

1. Prepare a local file from XML document by Calling the method IMPORT_FROM_FILE of class CL_XML_DOCUMENT_BASE .

2.For converting file to internal table, call the Funciton module GUI_DOWLOAD you can get all entries in internal table. (By passing input from the above step)

Regards

Bhupal Reddy

0 Kudos
280

hello bhupal,

1. I have the data in a <b>string</b> in the program.

2. i don't want all the data into an internal table, i want to traverse or read only particular nodes and get the data of nodes material, validfrom,validto.. to an internal table.

athavanraja
Active Contributor
0 Kudos
281

XLST program code (YSIMPLEXMLTOITAB)

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:strip-space elements="*"/>
  <xsl:output indent="yes"/>
  <xsl:template match="QfiData">
    <asx:abap xmlns:asx="http://www.sap.com/abapxml">
      <asx:values>
        <I_DATA>
          <xsl:for-each select="Materials">
            <I_DATA1>
              <MATERIAL>
                <xsl:value-of select="Material"/>
              </MATERIAL>
              <CONDITIONRATE>
                <xsl:value-of select="ConditionRate"/>
              </CONDITIONRATE>
              <VALIDFROM>
                <xsl:value-of select="ValidFrom"/>
              </VALIDFROM>
              <VALIDTO>
                <xsl:value-of select="ValidTo"/>
              </VALIDTO>
              <REGIONID>
                <xsl:value-of select="RegionID"/>
              </REGIONID>
              <MATERIALID>
                <xsl:value-of select="MaterialID"/>
              </MATERIALID>
            </I_DATA1>
          </xsl:for-each>
        </I_DATA>
      </asx:values>
    </asx:abap>
  </xsl:template>
</xsl:stylesheet>

Program to test it.

REPORT  y_test_xml_tran.

TYPES: BEGIN OF i_det,
Material(10),
ConditionRate(16) type p decimals 2 ,
ValidFrom(10) ,
ValidTo(10) ,
RegionID(3) ,
MaterialID(10) ,
end of i_det .
DATA: i_data TYPE TABLE OF i_det.
data: wa like line of i_data .

DATA: xml_string TYPE string .
DATA: xslt_error	TYPE REF TO	cx_xslt_exception,
xslt_message	TYPE	string .

CLEAR xml_string .
CONCATENATE

`<?xml version="1.0" encoding="utf-8"?>`
`<QfiData xmlns:xsl="http://www2.siemens.nl/qfiservice/QfiData.xsd">`
`<Materials>`
`<Material>463581</Material>`
`<ConditionRate> 2.44</ConditionRate>`
`<ValidFrom>20060208</ValidFrom>`
`<ValidTo>99991231</ValidTo>`
`<RegionID>48</RegionID>`
`<MaterialID>36294</MaterialID>`
`</Materials>`
`<Materials>`
`<Material>463582</Material>`
`<ConditionRate> 2.44</ConditionRate>`
`<ValidFrom>20060208</ValidFrom>`
`<ValidTo>99991231</ValidTo>`
`<RegionID>48</RegionID>`
`<MaterialID>36295</MaterialID>`
`</Materials>`
`</QfiData>`
INTO xml_string .


TRY .
    CALL TRANSFORMATION (`YSIMPLEXMLTOITAB`)
    SOURCE XML  xml_string
    RESULT     i_data = i_data.
  CATCH cx_xslt_exception INTO xslt_error.
    xslt_message = xslt_error->get_text( ).
ENDTRY.

Regards

Raja

0 Kudos
280

Hello Raj,

I don't know XLST. how to create the XLST?

0 Kudos
280

which version of R/3 you are using?

the code i had given can only be used in WAS6.10 or above (4.7)

to create XSLT program go to transaction Se80-> click on the button edit object->in the resulting dialog choose transformation radiobutton->enter name and click create. in the resulting editor, copy paste the xslt code given.

Regards

Raja

0 Kudos
280

hello raj,

I have created the XLST program as below and implemented the logic.

<xsl:transform version="1.0"

xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

xmlns:sapxsl="http://www.sap.com/sapxsl"

>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:strip-space elements="*"/>

<xsl:output indent="yes"/>

<xsl:template match="QfiData">

<asx:abap xmlns:asx="http://www.sap.com/abapxml">

<asx:values>

<I_DATA>

<xsl:for-each select="Materials">

<I_DATA1>

<MATERIAL>

<xsl:value-of select="Material"/>

</MATERIAL>

<CONDITIONRATE>

<xsl:value-of select="ConditionRate"/>

</CONDITIONRATE>

<VALIDFROM>

<xsl:value-of select="ValidFrom"/>

</VALIDFROM>

<VALIDTO>

<xsl:value-of select="ValidTo"/>

</VALIDTO>

<REGIONID>

<xsl:value-of select="RegionID"/>

</REGIONID>

<MATERIALID>

<xsl:value-of select="MaterialID"/>

</MATERIALID>

</I_DATA1>

</xsl:for-each>

</I_DATA>

</asx:values>

</asx:abap>

</xsl:template>

</xsl:stylesheet>

</xsl:transform>

But i am getting an error as below:

xlst:message = ABAP XML formatting error in XML node of type "element", name: "abap".

could you please help me.

0 Kudos
280

remove the following lines from your XSLT program

<xsl:transform version="1.0"

xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

xmlns:sapxsl="http://www.sap.com/sapxsl"

>

&

</xsl:transform>

Raja

0 Kudos
280

hello raja,

thankyou. the example code is working very good. but i still have problem when i try to implement it with the actual program.

I am getting this error: <b> ABAP XML formatting error in XML node of type "element", name: "abap"

0 Kudos
280

Hello raja,

Is it necessary that QfiData should be the starting tag. Actually i have a complex/huge xml file. From that file i have read only the material details.

The actual xml file looks as below:

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

<DataSet xmlns="http://www2.siemens.nl/qfiservice">

<xs:schema id="QfiData" targetNamespace="http://www2.siemens.nl/qfiservice/QfiData.xsd" xmlns:mstns="http://www2.siemens.nl/qfiservice/QfiData.xsd" xmlns="http://www2.siemens.nl/qfiservice/QfiData.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" attributeFormDefault="qualified" elementFormDefault="qualified">

<xs:element name="QfiData" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">

<xs:complexType>

<xs:choice minOccurs="0" maxOccurs="unbounded">

<xs:element name="Material">

<xs:complexType>

<xs:sequence>

<xs:element name="Material" type="xs:int" minOccurs="0" />

<xs:element name="ConditionRate" minOccurs="0">

<xs:simpleType>

<xs:restriction base="xs:string">

<xs:maxLength value="50" />

</xs:restriction>

</xs:simpleType>

</xs:element>

<xs:element name="ValidFrom" msdata:ReadOnly="true" minOccurs="0">

<xs:simpleType>

<xs:restriction base="xs:string">

<xs:maxLength value="8" />

</xs:restriction>

</xs:simpleType>

</xs:element>

<xs:element name="ValidTo" msdata:ReadOnly="true" minOccurs="0">

<xs:simpleType>

<xs:restriction base="xs:string">

<xs:maxLength value="8" />

</xs:restriction>

</xs:simpleType>

</xs:element>

<xs:element name="RegionID" msdata:ReadOnly="true" type="xs:int" minOccurs="0" />

<xs:element name="MaterialID" msdata:ReadOnly="true" msdata:AutoIncrement="true" type="xs:int" />

</xs:sequence>

</xs:complexType>

</xs:element>

<xs:element name="Pricegroup">

<xs:complexType>

<xs:sequence>

<xs:element name="ConditionRate" minOccurs="0">

<xs:simpleType>

<xs:restriction base="xs:string">

<xs:maxLength value="50" />

</xs:restriction>

</xs:simpleType>

</xs:element>

<xs:element name="PricegroupCpServ" minOccurs="0">

<xs:simpleType>

<xs:restriction base="xs:string">

<xs:maxLength value="50" />

</xs:restriction>

</xs:simpleType>

</xs:element>

<xs:element name="ValidFrom" msdata:ReadOnly="true" minOccurs="0">

<xs:simpleType>

<xs:restriction base="xs:string">

<xs:maxLength value="8" />

</xs:restriction>

</xs:simpleType>

</xs:element>

<xs:element name="ValidTo" msdata:ReadOnly="true" minOccurs="0">

<xs:simpleType>

<xs:restriction base="xs:string">

<xs:maxLength value="8" />

</xs:restriction>

</xs:simpleType>

</xs:element>

<xs:element name="RegionID" msdata:ReadOnly="true" type="xs:int" minOccurs="0" />

<xs:element name="PricegroupID" msdata:ReadOnly="true" msdata:AutoIncrement="true" type="xs:int" />

</xs:sequence>

</xs:complexType>

</xs:element>

</xs:choice>

</xs:complexType>

<xs:unique name="Constraint1" msdata:PrimaryKey="true">

<xs:selector xpath=".//mstns:Material" />

<xs:field xpath="mstns:MaterialID" />

</xs:unique>

<xs:unique name="Pricegroup_Constraint1" msdata:ConstraintName="Constraint1" msdata:PrimaryKey="true">

<xs:selector xpath=".//mstns:Pricegroup" />

<xs:field xpath="mstns:PricegroupID" />

</xs:unique>

</xs:element>

</xs:schema>

<diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">

<QfiData xmlns="http://www2.siemens.nl/qfiservice/QfiData.xsd">

<Material diffgr:id="Material1" msdata:rowOrder="0">

<Material>463581</Material>

<ConditionRate> 2.44</ConditionRate>

<ValidFrom>20060208</ValidFrom>

<ValidTo>99991231</ValidTo>

<RegionID>48</RegionID>

<MaterialID>36294</MaterialID>

</Material>

<Material diffgr:id="Material2" msdata:rowOrder="1">

<Material>463582</Material>

<ConditionRate> 2.44</ConditionRate>

<ValidFrom>20060208</ValidFrom>

<ValidTo>99991231</ValidTo>

<RegionID>48</RegionID>

<MaterialID>36295</MaterialID>

</Material>

<Material diffgr:id="Material3" msdata:rowOrder="2">

<Material>461691</Material>

<ConditionRate> 4.96</ConditionRate>

<ValidFrom>20060208</ValidFrom>

<ValidTo>99991231</ValidTo>

<RegionID>48</RegionID>

<MaterialID>36296</MaterialID>

</Material>

0 Kudos
280

if you look at the example , i have slightly modified the XML, may be post the actual XML file, i will come up with the suggestion.

Regards

Raja

Awarding points to helpful posts is SDN way of saying thanks. you can do this by choosing appropriate radiobuttons in the answers

0 Kudos
280

try this alternate approach, in the mean time you can mail me the actual XML file (you can find my id in the business card) i will come up with the XSLT program.

report y_xml_upload
       no standard page heading.
       data: filename type string ,
             xmldata type xstring .
data: result_xml type standard table of smum_xmltb .
data: return type standard table of bapiret2 .
 constants: line_size type i value 255.
  data: begin of xml_tab occurs 0,
           raw(line_size) type x,
        end   of xml_tab,
        file  type string,
        size  type i.

* upload the xml file
filename = 'C:rajabw.xml' .
  call function 'GUI_UPLOAD'
    exporting
      filename            = filename
      filetype            = 'BIN'
      has_field_separator = ' '
      header_length       = 0
    importing
      filelength          = size
    tables
      data_tab            = xml_tab
    exceptions
      others              = 1.
************uncomment this and comment the call of SCMS_BINARY_TO_XSTRING if you dont have this fm in your system.
*  if sy-subrc <> 0.
*    clear: xmldata.
*    exit.
*  else.
*    data: len type i.
*    len = size.
*    loop at xml_tab.
*      if len <= line_size. exit. endif.
*      concatenate xmldata xml_tab-raw(line_size)
*             into xmldata in byte mode.
*      len = len - line_size.
*    endloop.
*    if len > 0.
*      concatenate xmldata xml_tab-raw(len)
*             into xmldata in byte mode.
*      len = len - size.
*    endif.
*  endif.
******* end of comment.

call function 'SCMS_BINARY_TO_XSTRING'
  exporting
    input_length       = size
*   FIRST_LINE         = 0
*   LAST_LINE          = 0
 importing
   buffer             = xmldata
  tables
    binary_tab         = xml_tab
 exceptions
   failed             = 1
   others             = 2
          .
if sy-subrc <> 0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*         WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
endif.
call function 'SMUM_XML_PARSE'
  exporting
    xml_input       = xmldata
  tables
    xml_table       = result_xml
    return          = return .

Regards

Raja

0 Kudos
280

Hi raja,

Still the problem exists:

Error message : ABAP XML formatting error in XML node of type "element", name: "abap"

0 Kudos
280

i tried the alternate approach suggested (byme) with the file you had sent and it works fine.

(youhave to change the file location in the code filename = 'C:\...material.xml' .).

the only difference in this method is all xml elements are stored in the tab as name value pair, which you have to loop thru to get the data.

Regards

Raja

0 Kudos
280

hello raja,

could you please check the gmail for the latest query. i will send you the code, xml file and xslt.

actually the example program works fine. when when i try to import the actual xml file. there is an error.

please have a look and help me.

0 Kudos
280

the problem, is that the following mandatory line is nt there in the xml file.

<?xml version="1.0" encoding="utf-8"?> , it has to be there.

Regards

Raja

0 Kudos
280

i am sorry raja. i have already check that. no good result even if i include the

<?xml version="1.0" encoding="utf-8"?> mandatory string.

0 Kudos
280

hi raja,

Thank you very much. The alternative method is working fine. points rewarded.

But i would like know couple of things:

1. As you know i don't upload the data. But i get the xml file as a response and i have xml file in "xml_string" in text mode. Now i want to use the "SMUM_XML_PARSE".

Can you just tell me how?

0 Kudos
280
data: xml_string type string ,
      xml_xstring type xstring ,
      encoding type abap_encoding ,
      applencoding type cpcodepage.
 
call function 'SCP_GET_CODEPAGE_NUMBER'
          importing
            appl_codepage = applencoding.

    encoding = applencoding.


      call function 'SCMS_STRING_TO_XSTRING'
        exporting
          text           = xml_string
          encoding       = encoding
        importing
          buffer         = xml_xstring
        exceptions
         failed         = 1
         others         = 2.

now you can use xml_xstring with the function module.

Regards

Raja

0 Kudos
280

hi raja.

Super. Thats great man. Its works perfectly. Thank you very much.

0 Kudos
280

hi raja,

I am still interested to know about the mistake in XSLT. It was woking fine for the example code but not for the business requirement.

I would like to know the solution can you help me in this regard. i will be writing a new thread. As you the subject very well. Please do answer to that thread.

Former Member
0 Kudos
280

HI,

See the below links, this is useful for you

/people/tobias.trapp/blog/2006/10/06/xml-processing-in-abap-part-9-150-abap-processing-using-xslt

http://searchtechtarget.techtarget.com/generic/0,295582,sid21_gci1207657,00.html

Regards

Sudheer

Former Member
0 Kudos
280

Hi,

Please refer the thread,

Rgds,

Prakash