1. shaila panwar
  2. Beta Testing
  3. Monday, 16 December 2019 00:00 AM UTC

Since the support of webservice component had end in the PowerBuilder we have to change the strategy to transform and generate the xml.
I have been reading about the PBDOM for the XML parsing and this works well, But how about the generation of the XML from the values in the Structure and send this as a input to HTTPClient.

I am stuck on how we can generate the structured XML using PBDOM since we have the data in the nested Structures.

My structure definition is something like attached which has nested structures in it and I would like to generate the XML using PBDOM which can be formed like the attached XML.

 

 

The XML I want should be something like below:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="servlet.sam.can.tan.com" xmlns:wsto="http://wsto.sam.can.tan.com">

<soapenv:Header>

<soapenv:Body>

<ser:saveCurrentPosition>

<wsto:positionTO>
<wsto:positionCode>?</wsto:positionCode>
<wsto:loan>
<!--Zero or more repetitions:-->
<ser:item>
<wsto:loanId>?</wsto:loanId>
<wsto:extAccountId>?</wsto:extAccountId>
<wsto:creditApplId>?</wsto:creditApplId>
<wsto:creditApplLoanId>?</wsto:creditApplLoanId>
<wsto:accountNum>?</wsto:accountNum>
<wsto:bsbNum>?</wsto:bsbNum>
<wsto:loanTypeCd>?</wsto:loanTypeCd>
<wsto:productCd>?</wsto:productCd>
<wsto:productNameLong>?</wsto:productNameLong>
<wsto:productNameShort>?</wsto:productNameShort>
<wsto:interestRatePct>?</wsto:interestRatePct>
<wsto:originalLoanAmt>?</wsto:originalLoanAmt>
<wsto:balanceAmt>?</wsto:balanceAmt>
<wsto:interestCapFlag>?</wsto:interestCapFlag>
<wsto:originalLoanTerm>?</wsto:originalLoanTerm>
<wsto:firstHomeBuyerFlag>?</wsto:firstHomeBuyerFlag>
<wsto:remainingLoanTerm>?</wsto:remainingLoanTerm>
<wsto:lendingLimitAmt>?</wsto:lendingLimitAmt>
<wsto:llvrBalanceAmount>?</wsto:llvrBalanceAmount>
<wsto:loanRepaymentAmt>?</wsto:loanRepaymentAmt>
<wsto:lenderCd>?</wsto:lenderCd>
<wsto:lenderName>?</wsto:lenderName>
<wsto:lenderContactName>?</wsto:lenderContactName>
<wsto:addressId>?</wsto:addressId>
<wsto:specialConcessionCd>?</wsto:specialConcessionCd>
<wsto:borrowerTypeCd>?</wsto:borrowerTypeCd>
<wsto:securitisedLoanFlag>?</wsto:securitisedLoanFlag>
<wsto:loanPaidOutFlag>?</wsto:loanPaidOutFlag>
<wsto:closingFlag>?</wsto:closingFlag>
<wsto:paymentTypeCd>?</wsto:paymentTypeCd>
<wsto:updateSequenceId>?</wsto:updateSequenceId>
<wsto:dmSourceCd>?</wsto:dmSourceCd>
<wsto:deleteFlag>?</wsto:deleteFlag>
<wsto:dataStateTO>
<wsto:modificationStatus>?</wsto:modificationStatus>
<wsto:source>?</wsto:source>
</wsto:dataStateTO>
</ser:item>
</wsto:loan>

</wsto:positionTO>

</ser:saveCurrentPosition>

</soapenv:Body>

</soapenv:Header>

</soapenv:Envelope >

 

 

I have used below code but it is not generating the namespace on the new element which is being added:

lpbdom_builder = Create PBDOM_Builder

lpbdom_doc = lpbdom_builder.BuildFromString(ls_xml)

root_element = lpbdom_doc.GetRootElement()
ls_Text = root_element.GetName()

root_element.AddNameSpaceDeclaration('wsto',"http://wsto.sam.edscs.eds.com")
root_element.SetNameSpace('wsto',"http://wsto.sam.edscs.eds.com",false)

root_element.AddNameSpaceDeclaration('ser',"servlet.sam.edscs.eds.com")
root_element.SetNameSpace('ser',"servlet.sam.edscs.eds.com",false)

root_element.AddNameSpaceDeclaration('soapenv',"http://schemas.xmlsoap.org/soap/envelope/")
root_element.SetNameSpace('soapenv',"http://schemas.xmlsoap.org/soap/envelope/",false)
root_element.GetContent(lpbdom_obj)

lpbdom_element2 = Create PBDOM_Element

lpbdom_element2.SetName("Header")
root_element.AddContent(lpbdom_element2)

ls_attribute_name = lpbdom_doc.SaveDocumentIntoString()

 

 

Similarly this XML is nested structure  so how to add child element under the nested structure.

 

Mark Lee @Appeon Accepted Answer Pending Moderation
  1. Wednesday, 18 December 2019 07:52 AM UTC
  2. Beta Testing
  3. # 1

Hi Shaila,

For the question "how to add child element in the PBDOM function", you can check the following code if it works for you.

Code Example:

 

root_element.GetContent(lpbdom_obj)
integer li_Counter, li_Max
li_Max = UpperBound( lpbdom_Obj )
FOR li_Counter = 1 TO li_Max
   CHOOSE CASE    lpbdom_Obj[ li_Counter].GetObjectClassString()
      CASE "pbdom_processinginstruction"
            ls_Disp = ": " + lpbdom_Obj[ li_Counter].DYNAMIC GetData()
      CASE "pbdom_text"
            ls_Disp = ": " + lpbdom_Obj[ li_Counter].DYNAMIC GetText()
      CASE "pbdom_element"
            if lpbdom_Obj[ li_Counter].DYNAMIC HasChildElements() then 
               lpbdom_Obj[ li_Counter].DYNAMIC GetChildElements(child_element)
               li_count  =  UpperBound( child_element )
               for i =1 to li_count
                  ls_Text = child_element[li_count].getname( )
                  ls_Text = child_element[li_count].gettext( )
                  if child_element[i].haschildelements( ) then                                                                                                                                                               
                    child_element[i].getchildelements(secondchild_element)                                                                                       
                    li_count2 =  UpperBound( secondchild_element )                                                                                         
                    for j = 1 to li_count2                                                                                   
                       ls_Text = secondchild_element[j].getname( )                                                                                                    
                       secondchild_element[j].settext( "new values")
                       ....                                                                                                        
                    next                                                                      
                  end if 
                next 
              end if 
         CASE ELSE
              ls_Disp = ": " + lpbdom_Obj[ li_Counter ].GetText() 
       END CHOOSE      
NEXT

You can also refer to the following links:

https://docs.appeon.com/appeon_online_help/pb2019/extension_reference/ch13s01.html#XREF_42463_SetAttributes

https://docs.appeon.com/appeon_online_help/pb2019/extension_reference/ch13s01.html#XREF_83501_GetChildElements

 

Regards,

Comment
There are no comments made yet.
Marco Meoni Accepted Answer Pending Moderation
  1. Tuesday, 17 December 2019 07:42 AM UTC
  2. Beta Testing
  3. # 2

Hi Shaila,

this article explains you how to generate XML with PBDOM and contains a few examples too.

https://community.appeon.com/index.php/articles-blogs/tutorials-articles/2-powerbuilder/131-pbdom-with-powerbuilder

Since you are going to use PBDOM from a traditional PB WS target, bear in mind that SOAP service is an obsolete PB feature and you may want to replace it with the new C# REST API available in PB 2019 (HTTPClient will still be valid client). In this case, generate a (nested) XML is very simple too, and you'll find lots of C# examples online:

System.Xml.XmlDocument xdoc = new System.Xml.XmlDocument();
System.Xml.XmlDeclaration dec = xdoc.CreateXmlDeclaration("1.0", "UTF-8", null);
System.Xml.XmlElement root = xdoc.CreateElement("myroot");
xdoc.InsertBefore(dec, xdoc.DocumentElement);
xdoc.AppendChild(root);
// append more elements
xdoc.Save(fileName);

Best,

.m

Comment
  1. shaila panwar
  2. Tuesday, 17 December 2019 23:24 PM UTC
Thanks Marco,



I am going to use the HTPCLient only to communicate with my webservice , the sample is generated from the SOAP UI, hence it is mentioned SOAP in it.



The problem is with the traditional proxy generation object assembly dll's are generated and we do not need to worry about writing the XML Serialization and De-Serialization.

Now the option is obsolete, and we have to handle the serialization and de-serialization on the PB code.

PBDOM is not giving the expected result in my case.

Our existing design is everything gets populated into nested structures and we do not want to change that else it will result in writing the entire application again.

So, the only option remaining with us is to write the XML Serialization and De-Serialization which populates the structures and generate the XML from the PB Structures.

I am totally new in this field so wanted to understand the best approach to achieve this.

Is writing the Serialization and de-serialization method is feasible in PowerBuilder? if we are not dealing with the datawindows?

I tried the PBDOM and I must rule that out for generation of XML for the parsing it is good but not for the xml generation.

The other option I am looking for is using the C# DLL's which can be used as external function in PB to do this Job.



Or if there is any other way of doing this in PB?

I am looking for options which can replace the Assembly DLL generated by Proxy generator to do this job.

I need opinion about this.









  1. Helpful
There are no comments made yet.
  • Page :
  • 1


There are no replies made for this question yet.
However, you are not allowed to reply to this question.