Version 5 XML load using XML v6.0 DOMDocument for XML file with schema

borealis
Member Posts: 35
Client is running version 5.0.33335
Apologies if this is an answered question, I'm not having a lot of luck trying to search for answers on this one.
In the past I've found and used code to read in XML documents for ancient NAV using the 'Microsoft XML, v6.0'.DOMDocument60 control without issue. I'm not actually particularly proficient with this as most of our clients use later versions of NAV that allow me to use XML ports, but for this particular client upgrading is unfortunately not likely to happen in the forseeable future.
So my past code would simply use the XMLDoc.load command and then parse through the child nodes in a fairly straightforward way. Now, however the customer wants to receive XML documents that have a schema. Specifically <ORDER version="2.1" type="standard" xmlns="http://www.opentrans.org/XMLSchema/2.1" xmlns:bmecat="http://www.bmecat.org/bmecat/2005">. When I use the load command it returns false every time. As an experiment, I stripped out the schema specific stuff from a sample of it and the load proceeded just fine and my child nodes were where I expected them.
I could, in theory, write a routine to strip out the schema stuff before proceeding on to my processing however if possible I'd like to avoid that. Is there a way that I'm missing?
Past code was essentially this:
Apologies if this is an answered question, I'm not having a lot of luck trying to search for answers on this one.
In the past I've found and used code to read in XML documents for ancient NAV using the 'Microsoft XML, v6.0'.DOMDocument60 control without issue. I'm not actually particularly proficient with this as most of our clients use later versions of NAV that allow me to use XML ports, but for this particular client upgrading is unfortunately not likely to happen in the forseeable future.
So my past code would simply use the XMLDoc.load command and then parse through the child nodes in a fairly straightforward way. Now, however the customer wants to receive XML documents that have a schema. Specifically <ORDER version="2.1" type="standard" xmlns="http://www.opentrans.org/XMLSchema/2.1" xmlns:bmecat="http://www.bmecat.org/bmecat/2005">. When I use the load command it returns false every time. As an experiment, I stripped out the schema specific stuff from a sample of it and the load proceeded just fine and my child nodes were where I expected them.
I could, in theory, write a routine to strip out the schema stuff before proceeding on to my processing however if possible I'd like to avoid that. Is there a way that I'm missing?
Past code was essentially this:
IF ISCLEAR(XmlDoc) THEN CREATE(XmlDoc); XmlDoc.async(FALSE); okay := XmlDoc.load(Param.FileName); IF NOT okay THEN ERROR('That did not work'); // log an error CLEAR(EDIOrderHeader); InitNewOrder(EDIOrderHeader); XmlNodeList := XmlDoc.childNodes; FOR i := 0 TO XmlNodeList.length - 1 DO BEGIN XmlNode := XmlNodeList.item(i); ReadChildNodes(XmlNode,EDIOrderHeader); END;
0
Best Answer
-
I copy a paste your file and it load without a problem.
Here is the codeunit.OBJECT Codeunit 50195 Read XML ORDER { OBJECT-PROPERTIES { Date=10/11/17; Time=13:58:50; Modified=Yes; Version List=XML; } PROPERTIES { OnRun=BEGIN ReadXML('D:\Paso\pru2.xml'); END; } CODE { VAR i@1100000 : Integer; Acualizadas@1100001 : Integer; PROCEDURE ReadXML@1000000012(FileName@1100003 : Text[1024]); VAR XMLDoc@1100001 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 3.0:{F6D90F11-9C73-11D3-B32E-00C04F990BB4}:'Microsoft XML, v3.0'.DOMDocument"; XMLDocOut@1100000 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 3.0:{F6D90F11-9C73-11D3-B32E-00C04F990BB4}:'Microsoft XML, v3.0'.DOMDocument"; XMLNode@1100002 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 3.0:{2933BF80-7B36-11D2-B20E-00C04F983E60}:'Microsoft XML, v3.0'.IXMLDOMNode"; qText@1100004 : Text[50]; BEGIN CREATE(XMLDoc); IF NOT XMLDoc.load(FileName) THEN ERROR('ERROR loading file %1', FileName); RemoveNameSpace(XMLDoc, XMLDocOut); IF FindNode(XMLDocOut,'//ORDER_HEADER/ORDER_INFO/ORDER_ID',XMLNode) THEN BEGIN qText := XMLNode.text; MESSAGE('Order = %1', qText); END; CLEAR(XMLDoc); END; PROCEDURE RemoveNameSpace@1000000001(XMLSourceDoc@1000000001 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 3.0:{F6D90F11-9C73-11D3-B32E-00C04F990BB4}:'Microsoft XML, v3.0'.DOMDocument";VAR XMLDestinationDoc@1000000000 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 3.0:{F6D90F11-9C73-11D3-B32E-00C04F990BB4}:'Microsoft XML, v3.0'.DOMDocument"); VAR OutStreamStylesheet@1000000002 : OutStream; InStreamStylesheet@1000000003 : InStream; XMLStyleSheet@1000000004 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 3.0:{F6D90F11-9C73-11D3-B32E-00C04F990BB4}:'Microsoft XML, v3.0'.DOMDocument"; TempTable@1000000005 : TEMPORARY Record 79; BEGIN TempTable.Imagen.CREATEOUTSTREAM(OutStreamStylesheet); TempTable.Imagen.CREATEINSTREAM(InStreamStylesheet); OutStreamStylesheet.WRITETEXT('<?xml version="1.0" encoding="UTF-8"?>'); OutStreamStylesheet.WRITETEXT('<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">'); OutStreamStylesheet.WRITETEXT('<xsl:output method="xml" encoding="UTF-8" />'); OutStreamStylesheet.WRITETEXT('<xsl:template match="/">'); OutStreamStylesheet.WRITETEXT('<xsl:copy>'); OutStreamStylesheet.WRITETEXT('<xsl:apply-templates />'); OutStreamStylesheet.WRITETEXT('</xsl:copy>'); OutStreamStylesheet.WRITETEXT('</xsl:template>'); OutStreamStylesheet.WRITETEXT('<xsl:template match="*">'); OutStreamStylesheet.WRITETEXT('<xsl:element name="{local-name()}">'); OutStreamStylesheet.WRITETEXT('<xsl:apply-templates select="@* | node()" />'); OutStreamStylesheet.WRITETEXT('</xsl:element>'); OutStreamStylesheet.WRITETEXT('</xsl:template>'); OutStreamStylesheet.WRITETEXT('<xsl:template match="@*">'); OutStreamStylesheet.WRITETEXT('<xsl:attribute name="{local-name()}"><xsl:value-of select="."/></xsl:attribute>'); OutStreamStylesheet.WRITETEXT('</xsl:template>'); OutStreamStylesheet.WRITETEXT('<xsl:template match="text() | processing-instruction() | comment()">'); OutStreamStylesheet.WRITETEXT('<xsl:copy />'); OutStreamStylesheet.WRITETEXT('</xsl:template>'); OutStreamStylesheet.WRITETEXT('</xsl:stylesheet>'); IF ISCLEAR(XMLStyleSheet) THEN CREATE(XMLStyleSheet); XMLStyleSheet.load(InStreamStylesheet); IF ISCLEAR(XMLDestinationDoc) THEN CREATE(XMLDestinationDoc); XMLSourceDoc.transformNodeToObject(XMLStyleSheet,XMLDestinationDoc); END; PROCEDURE FindNode@3(XMLRootNode@1000 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 3.0:{2933BF80-7B36-11D2-B20E-00C04F983E60}:'Microsoft XML, v3.0'.IXMLDOMNode";NodePath@1001 : Text[250];VAR FoundXMLNode@1002 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 3.0:{2933BF80-7B36-11D2-B20E-00C04F983E60}:'Microsoft XML, v3.0'.IXMLDOMNode") : Boolean; BEGIN IF ISCLEAR(XMLRootNode) THEN EXIT(FALSE); FoundXMLNode := XMLRootNode.selectSingleNode(NodePath); IF ISCLEAR(FoundXMLNode) THEN EXIT(FALSE) ELSE EXIT(TRUE); END; BEGIN END. } }
5
Answers
-
If the problem is loading the XML file, looks like the file maybe is not a correct XML.
Could you put an example of this XML file ?
Regards0 -
I believe the issue is the fact it's running with two schemas. The Opentrans one, and the bmecat one. I've seen different XML controls that provide methods for loading those schemas, often in C++ but I have no idea how I might do that with this control in NAV with C/AL.
XML below, with some edits to remove customer specific names etc.<ORDER version="2.1" type="standard" xmlns="http://www.opentrans.org/XMLSchema/2.1" xmlns:bmecat="http://www.bmecat.org/bmecat/2005"> <ORDER_HEADER> <ORDER_INFO> <ORDER_ID>12563966</ORDER_ID> <ORDER_DATE>2017-08-22T00:00:00</ORDER_DATE> <bmecat:LANGUAGE>deu</bmecat:LANGUAGE> <PARTIES> <PARTY> <bmecat:PARTY_ID type="supplier_specific">4261</bmecat:PARTY_ID> <bmecat:PARTY_ID type="supplier_specific">0010</bmecat:PARTY_ID> <bmecat:PARTY_ID type="buyer_specific">1</bmecat:PARTY_ID> <bmecat:PARTY_ID type="buyer_specific">Party Name</bmecat:PARTY_ID> <bmecat:PARTY_ID type="buyer_specific">50A</bmecat:PARTY_ID> <PARTY_ROLE>buyer</PARTY_ROLE> <ADDRESS> <CONTACT_DETAILS> <bmecat:CONTACT_NAME>Doe, John</bmecat:CONTACT_NAME> <bmecat:PHONE>05231/14-555555</bmecat:PHONE> <bmecat:FAX>05231/14-555555</bmecat:FAX> </CONTACT_DETAILS> </ADDRESS> </PARTY> <PARTY> <bmecat:PARTY_ID type="buyer_specific">0000006416</bmecat:PARTY_ID> <bmecat:PARTY_ID type="party_specific">FDW</bmecat:PARTY_ID> <PARTY_ROLE>supplier</PARTY_ROLE> </PARTY> <PARTY> <bmecat:PARTY_ID type="supplier_specific">4261</bmecat:PARTY_ID> <bmecat:PARTY_ID type="buyer_specific">0010</bmecat:PARTY_ID> <PARTY_ROLE>delivery</PARTY_ROLE> <ADDRESS> <bmecat:NAME>Company Name</bmecat:NAME> <bmecat:NAME2>Logistik Center</bmecat:NAME2> <bmecat:STREET>Street address 1</bmecat:STREET> <bmecat:ZIP>55555</bmecat:ZIP> <bmecat:CITY>Detmold</bmecat:CITY> <bmecat:COUNTRY_CODED>DE</bmecat:COUNTRY_CODED> </ADDRESS> </PARTY> </PARTIES> <ORDER_PARTIES_REFERENCE> <bmecat:BUYER_IDREF>4261</bmecat:BUYER_IDREF> <bmecat:SUPPLIER_IDREF>0000006416</bmecat:SUPPLIER_IDREF> <SHIPMENT_PARTIES_REFERENCE> <DELIVERY_IDREF>4261</DELIVERY_IDREF> </SHIPMENT_PARTIES_REFERENCE> </ORDER_PARTIES_REFERENCE> <bmecat:CURRENCY>SEK</bmecat:CURRENCY> </ORDER_INFO> </ORDER_HEADER> <ORDER_ITEM_LIST> <ORDER_ITEM> <LINE_ITEM_ID>2</LINE_ITEM_ID> <PRODUCT_ID> <bmecat:SUPPLIER_PID>000000002484730000</bmecat:SUPPLIER_PID> <bmecat:BUYER_PID>2484730000</bmecat:BUYER_PID> </PRODUCT_ID> <PRODUCT_COMPONENTS> <PRODUCT_COMPONENT> <PRODUCT_ID> <bmecat:SUPPLIER_PID>000000002484730000</bmecat:SUPPLIER_PID> <bmecat:BUYER_PID>2484730000</bmecat:BUYER_PID> <bmecat:DESCRIPTION_SHORT>1492-MT5X12 ROHWARE</bmecat:DESCRIPTION_SHORT> </PRODUCT_ID> <QUANTITY>1000.00</QUANTITY> <bmecat:ORDER_UNIT>PCE</bmecat:ORDER_UNIT> </PRODUCT_COMPONENT> </PRODUCT_COMPONENTS> <QUANTITY>1000.00</QUANTITY> <bmecat:ORDER_UNIT>PCE</bmecat:ORDER_UNIT> <PRODUCT_PRICE_FIX> <bmecat:PRICE_AMOUNT>4.47</bmecat:PRICE_AMOUNT> <bmecat:PRICE_QUANTITY>100</bmecat:PRICE_QUANTITY> </PRODUCT_PRICE_FIX> <DELIVERY_DATE> <DELIVERY_START_DATE>2017-09-01T00:00:00</DELIVERY_START_DATE> <DELIVERY_END_DATE>2017-09-01T00:00:00</DELIVERY_END_DATE> </DELIVERY_DATE> <REMARKS type="order"> 461050/01</REMARKS> </ORDER_ITEM> <ORDER_ITEM> <LINE_ITEM_ID>4</LINE_ITEM_ID> <PRODUCT_ID> <bmecat:SUPPLIER_PID>000000002484750000</bmecat:SUPPLIER_PID> <bmecat:BUYER_PID>2484750000</bmecat:BUYER_PID> </PRODUCT_ID> <PRODUCT_COMPONENTS> <PRODUCT_COMPONENT> <PRODUCT_ID> <bmecat:SUPPLIER_PID>000000002484750000</bmecat:SUPPLIER_PID> <bmecat:BUYER_PID>2484750000</bmecat:BUYER_PID> <bmecat:DESCRIPTION_SHORT>1492-MT8X12 ROHWARE</bmecat:DESCRIPTION_SHORT> </PRODUCT_ID> <QUANTITY>2000.00</QUANTITY> <bmecat:ORDER_UNIT>PCE</bmecat:ORDER_UNIT> </PRODUCT_COMPONENT> </PRODUCT_COMPONENTS> <QUANTITY>2000.00</QUANTITY> <bmecat:ORDER_UNIT>PCE</bmecat:ORDER_UNIT> <PRODUCT_PRICE_FIX> <bmecat:PRICE_AMOUNT>5.11</bmecat:PRICE_AMOUNT> <bmecat:PRICE_QUANTITY>100</bmecat:PRICE_QUANTITY> </PRODUCT_PRICE_FIX> <DELIVERY_DATE> <DELIVERY_START_DATE>2017-09-01T00:00:00</DELIVERY_START_DATE> <DELIVERY_END_DATE>2017-09-01T00:00:00</DELIVERY_END_DATE> </DELIVERY_DATE> <REMARKS type="order">12345ASDFRE009</REMARKS> <REMARKS type="order"> 461052/01</REMARKS> </ORDER_ITEM> </ORDER_ITEM_LIST> <ORDER_SUMMARY> <TOTAL_ITEM_NUM>2</TOTAL_ITEM_NUM> <TOTAL_AMOUNT>146.90</TOTAL_AMOUNT> </ORDER_SUMMARY> </ORDER>
0 -
I copy a paste your file and it load without a problem.
Here is the codeunit.OBJECT Codeunit 50195 Read XML ORDER { OBJECT-PROPERTIES { Date=10/11/17; Time=13:58:50; Modified=Yes; Version List=XML; } PROPERTIES { OnRun=BEGIN ReadXML('D:\Paso\pru2.xml'); END; } CODE { VAR i@1100000 : Integer; Acualizadas@1100001 : Integer; PROCEDURE ReadXML@1000000012(FileName@1100003 : Text[1024]); VAR XMLDoc@1100001 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 3.0:{F6D90F11-9C73-11D3-B32E-00C04F990BB4}:'Microsoft XML, v3.0'.DOMDocument"; XMLDocOut@1100000 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 3.0:{F6D90F11-9C73-11D3-B32E-00C04F990BB4}:'Microsoft XML, v3.0'.DOMDocument"; XMLNode@1100002 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 3.0:{2933BF80-7B36-11D2-B20E-00C04F983E60}:'Microsoft XML, v3.0'.IXMLDOMNode"; qText@1100004 : Text[50]; BEGIN CREATE(XMLDoc); IF NOT XMLDoc.load(FileName) THEN ERROR('ERROR loading file %1', FileName); RemoveNameSpace(XMLDoc, XMLDocOut); IF FindNode(XMLDocOut,'//ORDER_HEADER/ORDER_INFO/ORDER_ID',XMLNode) THEN BEGIN qText := XMLNode.text; MESSAGE('Order = %1', qText); END; CLEAR(XMLDoc); END; PROCEDURE RemoveNameSpace@1000000001(XMLSourceDoc@1000000001 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 3.0:{F6D90F11-9C73-11D3-B32E-00C04F990BB4}:'Microsoft XML, v3.0'.DOMDocument";VAR XMLDestinationDoc@1000000000 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 3.0:{F6D90F11-9C73-11D3-B32E-00C04F990BB4}:'Microsoft XML, v3.0'.DOMDocument"); VAR OutStreamStylesheet@1000000002 : OutStream; InStreamStylesheet@1000000003 : InStream; XMLStyleSheet@1000000004 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 3.0:{F6D90F11-9C73-11D3-B32E-00C04F990BB4}:'Microsoft XML, v3.0'.DOMDocument"; TempTable@1000000005 : TEMPORARY Record 79; BEGIN TempTable.Imagen.CREATEOUTSTREAM(OutStreamStylesheet); TempTable.Imagen.CREATEINSTREAM(InStreamStylesheet); OutStreamStylesheet.WRITETEXT('<?xml version="1.0" encoding="UTF-8"?>'); OutStreamStylesheet.WRITETEXT('<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">'); OutStreamStylesheet.WRITETEXT('<xsl:output method="xml" encoding="UTF-8" />'); OutStreamStylesheet.WRITETEXT('<xsl:template match="/">'); OutStreamStylesheet.WRITETEXT('<xsl:copy>'); OutStreamStylesheet.WRITETEXT('<xsl:apply-templates />'); OutStreamStylesheet.WRITETEXT('</xsl:copy>'); OutStreamStylesheet.WRITETEXT('</xsl:template>'); OutStreamStylesheet.WRITETEXT('<xsl:template match="*">'); OutStreamStylesheet.WRITETEXT('<xsl:element name="{local-name()}">'); OutStreamStylesheet.WRITETEXT('<xsl:apply-templates select="@* | node()" />'); OutStreamStylesheet.WRITETEXT('</xsl:element>'); OutStreamStylesheet.WRITETEXT('</xsl:template>'); OutStreamStylesheet.WRITETEXT('<xsl:template match="@*">'); OutStreamStylesheet.WRITETEXT('<xsl:attribute name="{local-name()}"><xsl:value-of select="."/></xsl:attribute>'); OutStreamStylesheet.WRITETEXT('</xsl:template>'); OutStreamStylesheet.WRITETEXT('<xsl:template match="text() | processing-instruction() | comment()">'); OutStreamStylesheet.WRITETEXT('<xsl:copy />'); OutStreamStylesheet.WRITETEXT('</xsl:template>'); OutStreamStylesheet.WRITETEXT('</xsl:stylesheet>'); IF ISCLEAR(XMLStyleSheet) THEN CREATE(XMLStyleSheet); XMLStyleSheet.load(InStreamStylesheet); IF ISCLEAR(XMLDestinationDoc) THEN CREATE(XMLDestinationDoc); XMLSourceDoc.transformNodeToObject(XMLStyleSheet,XMLDestinationDoc); END; PROCEDURE FindNode@3(XMLRootNode@1000 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 3.0:{2933BF80-7B36-11D2-B20E-00C04F983E60}:'Microsoft XML, v3.0'.IXMLDOMNode";NodePath@1001 : Text[250];VAR FoundXMLNode@1002 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 3.0:{2933BF80-7B36-11D2-B20E-00C04F983E60}:'Microsoft XML, v3.0'.IXMLDOMNode") : Boolean; BEGIN IF ISCLEAR(XMLRootNode) THEN EXIT(FALSE); FoundXMLNode := XMLRootNode.selectSingleNode(NodePath); IF ISCLEAR(FoundXMLNode) THEN EXIT(FALSE) ELSE EXIT(TRUE); END; BEGIN END. } }
5 -
ftornero,
For some reason I cannot get your codeunit to work. It fails on the error when unable to load the file. The only change I made was to change the file/directory and the field name for the "picture" field in company information used as a temp table (which it never gets to since the error is before that).0 -
I don't know what to say, it's work for me, running the codeunit I get this message
The problem could be thatyou don't have enough permissions in the directory.
Regards0 -
After a bit of research on how to determine error codes, the problem turned out to be an illegal character. The sending company is german and had an ascii 129 (the u with two dots). I sanitized the company name in the xml file I pasted here which is why it wasn't a problem for you.
Is there a way to specify the allowable character set with the DOMDocument before the load? I'm looking at the MSDN set of methods for the objects but nothing is jumping out at me.0 -
In this case is a codification problem.
I changed the file from ANSI to UTF-8, inserted the u with two dots, and I loaded the file without a problem again.
0 -
Is there any way to specify the encoding of the file though prior to passing it through the load method? The XML envelope unfortunately doesn't specify the encoding, so it makes it somewhat problematic. All the xml from this particular client will likely be in the same format, so I shouldn't have to worry about inconsistency but I don't know how to tell the DOMDocument which encoding to use.0
-
What is the format of the file ?
If always is the same you can change to UTF-8 before loading.
Regards.0
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