我再次陷入从XML到ABAP的转变。这次,我想将XML数据直接放入ABAP对象中。
我的XML看起来像这样:
<qualityStatus>
<address>0</address>
<bounceRisk>0</bounceRisk>
<checked>1</checked>
<domain>1</domain>
<domainScores>
<domainScore>
<domain>gmx.de</domain>
<score>0.8333333134651184</score>
</domainScore>
<domainScore>
<domain>ggs.de</domain>
<score>0.6666666269302368</score>
</domainScore>
<domainScore>
<domain>xyz.de</domain>
<score>0.6666666269302368</score>
</domainScore>
</domainScores>
<extSyntax>1</extSyntax>
<mailserver>1</mailserver>
<mailserverDiagnosis>1</mailserverDiagnosis>
<probability>1</probability>
<syntax>1</syntax>
</qualityStatus>
编辑:我改回了XSLT转换,缩短为一个属性,如下所示:
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:sap="http://www.sap.com/sapxsl" version="1.0">
<xsl:output encoding="iso-8859-1" indent="yes" method="xml" version="1.0"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/qualityStatus">
<asx:abap version="1.0" xmlns:asx="http://www.sap.com/abapxml">
<asx:values>
<ROOT href="#o26"/>
</asx:values>
<asx:heap xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:abap="http://www.sap.com/abapxml/types/built-in"
xmlns:cls="http://www.sap.com/abapxml/classes/global"
xmlns:dic="http://www.sap.com/abapxml/types/dictionary">
<cls:ZCL_ADDRESS_QUALITY id="o26" >
<local.ZCL_ADDRESS_QUALITY>
<W_ADDRESS>
<xsl:value-of select="address"/>
</W_ADDRESS>
<!--More attributes here-->
</local.ZCL_ADDRESS_QUALITY>
</cls:ZCL_ADDRESS_QUALITY>
</asx:heap>
</asx:abap>
</xsl:template>
我的对象属性现在都是公开的,因为我认为这可能是问题所在。但是,确实存在setter和getter。是的,我的类确实实现了if_serializable_object接口。
DATA:
w_address TYPE char1,
w_bouncerisk TYPE char1,
w_checked TYPE char1,
w_decoded TYPE stringval,
w_domain TYPE char1,
w_domainscores TYPE z_domainscore_t, "Table type for name + score
w_extsyntax TYPE char1,
w_mailserver TYPE char1,
w_mailserverdiagnosis TYPE char1,
w_probability TYPE char1,
w_syntax TYPE char1,
w_syntaxwarnings TYPE z_syntaxwarnings_t. "Table of syntaxwarnings
最后,我用我的班级实例调用我的转换:
CALL TRANSFORMATION zst_addressquality
SOURCE XML lw_xml
RESULT result = lo_addressquality.
现在,在通过转换代码进行调试时,它成功地通知了给定lw_xml的所有字段,并且似乎将它们写入对象lo_addressquality。但是之后对象属性保持空白。
在测试序列化时,我可以访问包含我的对象的结果,但result-w_address(和所有其他的)都是空的。
在测试时,我创建了一个名称和类型完全相同的结构。有了它,它按预期工作。
我错过了什么?在转换到ABAP对象时,还有什么我需要注意的吗?
_Edit:在更改为XSLT之后,在代码抛出CX_XSLT_ABAP_CALL_ERROR之前,我可以直到W_ADDRESS。所以,我仍然无法正确访问对象的属性。 :| _
答案 0 :(得分:3)
只能通过 XSL 转换对象进行序列化/反序列化。使用简单的转换dixit ABAP documentation是不可能的:“ST程序仅限于基本和结构化ABAP数据的转换,以及内部表。目前不支持引用变量和引用对象的转换”
XSL转换必须将XML转换为ASXML,简而言之,对应于这样的结构:
<?xml ...?>
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
<asx:values>
...
</asx:values>
<asx:heap>
...
</asx:heap>
</asx:abap>
了解ASXML应该是什么样子的最简单方法是使用identity transformation(它是一个XSL转换)序列化对象引用,然后调整转换以生成相同类型的asXML:
CALL TRANSFORMATION id SOURCE anyRootName = yourObjectReference RESULT XML asXMLutf8xstring.
示例:
REPORT.
CLASS serialization_demo DEFINITION.
PUBLIC SECTION.
INTERFACES if_serializable_object.
DATA attribute TYPE i.
ENDCLASS.
START-OF-SELECTION.
DATA obj_ref TYPE REF TO serialization_demo.
DATA xstring TYPE xstring.
CREATE OBJECT obj_ref.
obj_ref->attribute = 5.
CALL TRANSFORMATION id " serialize
SOURCE root = obj_ref
RESULT XML xstring.
CLEAR obj_ref.
CALL TRANSFORMATION id " deserialize
SOURCE XML xstring
RESULT root = obj_ref.
ASXML(在xstring变量中):
<?xml version="1.0" encoding="utf-8"?>
<asx:abap version="1.0" xmlns:asx="http://www.sap.com/abapxml">
<asx:values>
<ROOT href="#o3"/>
</asx:values>
<asx:heap xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:abap="http://www.sap.com/abapxml/types/built-in" xmlns:cls="http://www.sap.com/abapxml/classes/global" xmlns:dic="http://www.sap.com/abapxml/types/dictionary">
<prg:SERIALIZATION_DEMO id="o3" xmlns:prg="http://www.sap.com/abapxml/classes/program/ZZSRO_TEST16I">
<local.SERIALIZATION_DEMO>
<ATTRIBUTE>5</ATTRIBUTE>
</local.SERIALIZATION_DEMO>
</prg:SERIALIZATION_DEMO>
</asx:heap>
</asx:abap>