2005 Aug 29 8:07 AM
Hi,
I have an Source XML as follows.
<ROOTNODE>
<A>value</A>
<B>value</B>
</ROOTNODE>
<ROOTNODE>
<A>value</A>
<B>value</B>
</ROOTNODE>
<CHILD1>
<A>value</A>
<B>value</B>
</CHILD1>
NOW AFTER PERFORMING XSLT I NEED TO GET THE RESULT XML AS FOLLOWS.
<ROOTNODE>
<ROOTNODE>
<A>value</A>
<B>value</B>
</ROOTNODE>
<ROOTNODE>
<A>value</A>
<B>value</B>
</ROOTNODE>
</ROOTNODE>
<CHILD1>
<CHILD1>
<A>value</A>
<B>value</B>
</CHILD1>
</CHILD1>
The problem is i donot know what elements will be coming in the source xml and i cant hardcode the element names in the xslt.
2005 Aug 29 8:23 AM
hi,
Try with OOPs method. here is the sample code
data :lo_mxml type ref to cl_xml_document,
m_document type ref to if_ixml_document,
l_dom type ref to if_ixml_element,
l_ele type ref to if_ixml_element,
l_ele1 type ref to if_ixml_element,
l_ele2 type ref to if_ixml_element,
l_ele3 type ref to if_ixml_element,
l_ele4 type ref to if_ixml_element,
l_ele5 type ref to if_ixml_element,
l_ele6 type ref to if_ixml_element,
l_ele7 type ref to if_ixml_element,
m_doctype type ref to if_ixml_document_type,
g_ixml type ref to if_ixml,
l_text type ref to if_ixml_text,
ls_srctab1 type xstring,
l_retcode type sysubrc. "#EC *.
create object lo_mxml.
perform header_xml.
l_retcode = lo_mxml->create_with_dom( document =
m_document ).
CALL METHOD LO_MXML->DISPLAY.
call method lo_mxml->render_2_xstring
exporting
pretty_print = 'X'
importing
retcode = l_retcode
stream = l_string.
class cl_ixml definition load.
g_ixml = cl_ixml=>create( ).
m_document = g_ixml->create_document( ).
call method m_document->create_document_type
exporting
name = 'cXML'
receiving
rval = m_doctype.
call method m_document->set_document_type
exporting
document_type = m_doctype.
call method l_dom->set_attribute
exporting
name = 'payloadID'
value = l_string
receiving
rval = l_retcode.
call method l_dom->set_attribute
exporting
name = 'timestamp'
value = l_string
receiving
rval = l_retcode.
*___HEADER NODE (CHILD OF CXML NODE)
l_ele = m_document->create_element( name = 'Header' ).
l_retcode = l_dom->append_child( l_ele ).
*___FROM NODE (CHILD OF HEADER NODE)
l_ele1 = m_document->create_element( name = 'From' ).
l_retcode = l_ele->append_child( l_ele1 ).
l_ele2 = m_document->create_element( name
= 'Credential' ).
l_retcode = l_ele1->append_child( l_ele2 ).
*____ATTRIBUTE FOR CREDENTIAL FROM NODE
move gc_cre_from to l_string.
call method l_ele2->set_attribute
exporting
name = 'domain'
value = l_string
receiving
rval = l_retcode.
Hope this will help for you
Cheers,
Sasi
2005 Aug 29 1:47 PM
Hi, I try to create a XSLT to meet your requirement, but can only archieve it in a static(hard code) way.
The XSLT file like following:
I add a whole target on your source XML
<?xml version="1.0"?>
<DATA>
<ROOTNODE>
<A>value</A>
<B>value</B>
</ROOTNODE>
<ROOTNODE>
<A>value</A>
<B>value</B>
</ROOTNODE>
<CHILD1>
<A>value</A>
<B>value</B>
</CHILD1>
</DATA>
my XSLT file
<?xml version='1.0' ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="DATA">
<ROOTNODE>
<xsl:for-each select="ROOTNODE">
<xsl:call-template name="DATA"/>
</xsl:for-each>
</ROOTNODE>
<CHILD1>
<xsl:for-each select="CHILD1">
<xsl:call-template name="DATA"/>
</xsl:for-each>
</CHILD1>
</xsl:template>
<xsl:template name="DATA">
<xsl:copy-of select="."/>
</xsl:template>
</xsl:stylesheet>
I think the critical point is to replace the hardcode <ROOTNODE> to be a dynamic.
Really hope some XSLT expert can support us solve this question.
2005 Aug 29 3:32 PM
Exactly, I dont want the hard coded stuf in the XSLT because i wll not be getting the Same xml every time. The Elements will be changed for each XmL. My XSLT should be generic.
2005 Aug 30 5:41 AM
This Transformation works.
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:sapxsl="http://www.sap.com/sapxsl" xmlns:asx="http://www.sap.com/abapxml" version="1.0" >
<xsl:strip-space elements="*"/>
<xsl:template match="/|*">
<xsl:element name="asx:abap">
<xsl:element name="asx:values">
<xsl:for-each select="//asx:values/*">
<xsl:variable name="segment1" select="name()"/>
<xsl:variable name="lastsegment" select="name(preceding-sibling::*[1])"/>
<xsl:if test="$segment1 != $lastsegment">
<xsl:element name="{$segment1}">
<xsl:for-each select="//asx:values/*">
<xsl:variable name="segment2" select="name()"/>
<xsl:if test="$segment1 = $segment2">
<xsl:element name="item">
<xsl:for-each select="./@*">
<xsl:variable name="fieldname" select="name()"/>
<xsl:element name="{$fieldname}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:if>
</xsl:for-each>
</xsl:element>
</xsl:if>
</xsl:for-each>
</xsl:element>
</xsl:element>
</xsl:template>
</xsl:transform>
2005 Aug 30 10:48 AM
Hi, great.
You xslt is very useful. And I do some change on it, then get the result we need.
The source XML is similar to my former post.
[code]
XSLT file:
<?xml version='1.0'?>
<xsl:transform version="1.0" xmlns:asx="http://www.sap.com/abapxml"
xmlns:sapxsl="http://www.sap.com/sapxsl" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<xsl:template match="/|*">
<xsl:element name="DATA">
<xsl:for-each select="//DATA/*">
<xsl:variable name="segment1" select="name()"/>
<xsl:variable name="lastsegment" select="name(preceding-sibling::*[1])"/>
<xsl:if test="$segment1 != $lastsegment">
<xsl:element name="{$segment1}">
<xsl:for-each select="//DATA/*">
<xsl:variable name="segment2" select="name()"/>
<xsl:if test="$segment1 = $segment2">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:for-each>
</xsl:element>
</xsl:if>
</xsl:for-each>
</xsl:element>
</xsl:template>
</xsl:transform>
Result XML:
<?xml version='1.0' ?>
<DATA>
<ROOTNODE>
<ROOTNODE>
<A>value</A>
<B>value</B>
</ROOTNODE>
<ROOTNODE>
<A>value</A>
<B>value</B>
</ROOTNODE>
</ROOTNODE>
<CHILD1>
<CHILD1>
<A>value</A>
<B>value</B>
</CHILD1>
</CHILD1>
</DATA>
[/code]
So gr8, the result looks prefects. thanks you for paste the helpful file.