How to import data from an XML file to BC tables?

isabtogumon
Member Posts: 50
Hello everyone,
I already have the data from the XML file in InStream, I need to access each node to obtain the data and insert it into a BC table. XML has several levels, in addition to being very extensive. How can I do it?
I have seen a method (y2u.be/x8AOo9j-ifE), however I have not managed to access the nodes. This is an example of the XML structure
I already have the data from the XML file in InStream, I need to access each node to obtain the data and insert it into a BC table. XML has several levels, in addition to being very extensive. How can I do it?
I have seen a method (y2u.be/x8AOo9j-ifE), however I have not managed to access the nodes. This is an example of the XML structure
<?xml version="1.0" encoding="UTF-8"?> <soap:Envelope> <soap:Body> <GetMovementResponse> <GetMovementResult> <Code>1</Code> <Message/> <Data></Data> <List> <Movement> <--- From here <Code>XXX</Code> <MovementType>XXX</MovementType> <DateMovement>2020-11-27T15:04:04.09</DateMovement> <OriginCompany> <ID>0</ID> </OriginCompany> <CenterCostSource> <ID>0</ID> <ExternalCode>1</ExternalCode> </CenterCostSource> . . . </Movement> +<Movement> +<Movement> . . .
0
Best Answer
-
Hello @isabtogumon
With this XML you need to use a name space manager to deal with the lien in green in the image.if XmlDocument.ReadFrom(InStr, xmlDoc) then begin xmlnsMgr.AddNamespace('ns', 'http://www.company.com.br/Company'); if xmlDoc.SelectNodes('//ns:Movement', xmlnsMgr, xmlNodList) then begin foreach xmlNod in xmlNodList do begin xmlNod.SelectSingleNode('ns:OriginCompany/ns:ID', xmlnsMgr, xmlNod2); Message(xmlNod2.AsXmlElement().InnerText); end; end; end;
And this is the new var:xmlnsMgr: XmlNamespaceManager;
Regards1
Answers
-
Hello @isabtogumon,
How you already have the xml in a Instream, you can do something like this to get, by example, the value of OriginCompany/ID of every Movementif XmlDocument.ReadFrom(InStr, xmlDoc) then begin if xmlDoc.SelectNodes('//Movement', xmlNodList) then begin foreach xmlNod in xmlNodList do begin xmlNod.SelectSingleNode('OriginCompany/ID', xmlNod2); Message(xmlNod2.AsXmlElement().InnerText); end; end; end;
Where the variables are:InStr: InStream; xmlDoc: XmlDocument; xmlNodList: XmlNodeList; xmlNod: XmlNode; xmlNod2: XmlNode;
Regards
1 -
Hello @ftornero, thanks for your answer
I tried your method but unfortunately it doesn't access the line:foreach xmlNod in xmlNodList do begin
I skipped that line and it shows me the following error:
Microsoft.Dynamics.Nav.Runtime.NavXmlNode variable not initialized.
I do not know if it is related to the fact that I did not enter the mentioned line0 -
0
-
Hello @ftornero
What I mean, at runtime it doesn't execute the "foreach" block, so it skips these lines:xmlNod.SelectSingleNode('OriginCompany/ID', xmlNod2); Message(xmlNod2.AsXmlElement().InnerText);
0 -
The easiest way you can do it, is parse the XML to the XMLBuffer and treat it like a simple table in BC.0
-
Hello @isabtogumon,
Then the problem is in the previous line, that is not selecting any node.if xmlDoc.SelectNodes('//Movement', xmlNodList) then begin
Could you post a reduced version of the XML file that you are reading ?
Regards0 -
Hello @JJMc
I had contemplated it and tried this procedure. However, it does not fill the table correctlyprocedure ImportXML() var XMLInStream: InStream; UploadResult: Boolean; DialogCaption: Text; XMLFileName: Text; XMLBuffer: Record "XML Buffer"; TMovimemtosWS: Record TMovimemtosWS; begin UploadResult := UploadIntoStream(DialogCaption, '', '', XMLFileName, XMLInStream); XMLBuffer.DeleteAll; XMLBuffer.LoadFromStream(XMLInStream); if XMLBuffer.FindSet() then repeat TMovimemtosWS.Validate(TipoMovimentacao, XMLBuffer.Value); TMovimemtosWS.Validate(DataMovimentacao, XMLBuffer.Value); TMovimemtosWS.Validate(TipoDocumento, XMLBuffer.Value); if not TMovimemtosWS.Insert() then TMovimemtosWS.Modify(); until XMLBuffer.Next() = 0; end;
I only consider three fields but this process does not fill them correctly
0 -
0
-
Hello @isabtogumon
With this XML you need to use a name space manager to deal with the lien in green in the image.if XmlDocument.ReadFrom(InStr, xmlDoc) then begin xmlnsMgr.AddNamespace('ns', 'http://www.company.com.br/Company'); if xmlDoc.SelectNodes('//ns:Movement', xmlnsMgr, xmlNodList) then begin foreach xmlNod in xmlNodList do begin xmlNod.SelectSingleNode('ns:OriginCompany/ns:ID', xmlnsMgr, xmlNod2); Message(xmlNod2.AsXmlElement().InnerText); end; end; end;
And this is the new var:xmlnsMgr: XmlNamespaceManager;
Regards1 -
0
-
@ftornero can you please explain how you have insert data in BC table.....I am trying with example but it not working
0 -
0
-
Take for example this xml file
I use the code below to import data from Azure blob storage into Customer table and Ship to Address Table
procedure ReadXML(InStr: InStream)
var
Customer: Record Customer;
ShiptoAddress: Record "Ship-to Address";
xmlDoc: XmlDocument;
CustomerTab: XmlElement;
NodeList: XmlNodeList;
NodeCustomerList: XmlNodeList;
Node: XmlNode;
XmlCustomerNode: XmlNode;
XmlShipToNode: XmlNode;
XmlCustomerElement: XmlElement;
XmlShipToElement: XmlElement;
begin
if XmlDocument.ReadFrom(InStr, xmlDoc) then begin
//Find the root element
if xmlDoc.GetRoot(CustomerTab) then
NodeList := CustomerTab.GetChildElements();
foreach Node in NodeList do begin
XmlCustomerElement := Node.AsXmlElement();
NodeCustomerList := XmlCustomerElement.GetChildElements();
foreach XmlCustomerNode in NodeCustomerList do begin
case XmlCustomerNode.AsXmlElement().Name of
'No.':
Customer.Validate(Customer."No.", XmlCustomerNode.AsXmlElement().InnerText);
'Name':
Customer.Validate(Customer.Name, XmlCustomerNode.AsXmlElement().InnerText);
'Address':
Customer.Validate(Customer.Address, XmlCustomerNode.AsXmlElement().InnerText);
'ShipToAddress':
begin
XmlShipToElement := XmlCustomerNode.AsXmlElement();
ShiptoAddress.Init();
ShiptoAddress.Validate("Customer No.", Customer."No.");
foreach XmlShipToNode in XmlShipToElement.GetChildElements() do begin
case XmlShipToNode.AsXmlElement().Name of
'Code':
ShiptoAddress.Code := XmlShipToNode.AsXmlElement().InnerText;
'ShipName':
ShiptoAddress.Name := XmlShipToNode.AsXmlElement().InnerText;
'PostCode':
ShiptoAddress.Validate("Post Code", XmlShipToNode.AsXmlElement().InnerText);
'Country':
ShiptoAddress.Validate("Country/Region Code", XmlShipToNode.AsXmlElement().InnerText);
end;
if not ShiptoAddress.Insert() then
ShiptoAddress.Modify();
end;
end;
end;
if not Customer.Insert() then
Customer.Modify();
end;
end;
end;
end;
0 -
Below is a screenshot for the above code
1
Categories
- All Categories
- 73 General
- 73 Announcements
- 66.6K Microsoft Dynamics NAV
- 18.7K NAV Three Tier
- 38.4K NAV/Navision Classic Client
- 3.6K Navision Attain
- 2.4K Navision Financials
- 116 Navision DOS
- 851 Navision e-Commerce
- 1K NAV Tips & Tricks
- 772 NAV Dutch speaking only
- 617 NAV Courses, Exams & Certification
- 2K Microsoft Dynamics-Other
- 1.5K Dynamics AX
- 320 Dynamics CRM
- 111 Dynamics GP
- 10 Dynamics SL
- 1.5K Other
- 990 SQL General
- 383 SQL Performance
- 34 SQL Tips & Tricks
- 35 Design Patterns (General & Best Practices)
- 1 Architectural Patterns
- 10 Design Patterns
- 5 Implementation Patterns
- 53 3rd Party Products, Services & Events
- 1.6K General
- 1.1K General Chat
- 1.6K Website
- 83 Testing
- 1.2K Download section
- 23 How Tos section
- 252 Feedback
- 12 NAV TechDays 2013 Sessions
- 13 NAV TechDays 2012 Sessions