Hello,
has anyone got some experience with the XMLPorts provided bij Navision 4.0?
I'm trying to import an xml-file which has a namespace "xmlns:xsi" defined. The xmldocument looks something like:
<MyTest xmlns:xsi="
http://www.w3.org/2001/XMLSchema-instance">
<MyElement>SomeValue</MyElement>
</MyTest>
When I try to import this document I always get the following error message from navision:
"The namespace
http://www.w3.org/2001/XMLSchem-instance has not been defined at object".
This message can't be found using the debugger. Thus I presume that the database engine generates this error.
I also can't find a place to put the namespace in the XMLPort definition. Searching for a place to put the namespace in the XMLPort definition I also tried putting the namespace as an attribute of the element "MyTest". But that didn't help much.
Without the namespace the import works just fine.
Has anybody got some idea?
Comments
GAC Business Solutions B.V.
RIS Plus, LLC
Because in my case, i've got:
<rss version="2.0" xmlns:content="[url]">
I've found a work around for this problem.
I replaced that line with one w/o the xmlns:content="" Attribute
like this:
[/url]
IntCounter must be (in my case) 2 because it's ALWAYS on the 3rd line of the file. After running this you'll be able to import file_fixed.xml
GAC Business Solutions B.V.
I have tried adding the namespace attributes in various ways to the XMLPort itself but nothing seems to work.
you cannot use XML Files with Namespace in XML Ports.
This is not working.
(Don't ask me why.. I just know that it doesn't)
(You have to remove this 1st)
Yours
Stephan
Stephan
It links to an article in partnersource... https://mbs.microsoft.com/partnersource/documentation/howtoarticles/xmlportswebservices.htm?printpage=false
Anyone care to share the knowledge with us non-partners?
Here you are...
Overview:
A web service is a programmatic interface for application to application communication through the internet. The communication protocol is based on XML documents. An XML document usually contains namespaces to qualify its element and attribute names. Both applications must support namespaces to communicate.
XMLports in Navision can be used to generate XML documents and communicate with web services. But they do not support namespaces in version 4.00. A simple method is described in this article to get around this limitation.
Technical:
To communicate with a web service, XMLports in Navision need to send and receive XML documents containing namespaces.
1. Sending XML documents
In the XMLport, the TagType “Attribute” can be used to define XML namespaces.
For example, add the following tag in an XMLport:
TagName: xmlns
TagType: Attribute
SourceType: Text
DataSource: xmlns1
Add the following C/AL code line in the OnPreXMLport() trigger of the XMLport:
xmlns1 := 'http://schemas.xmlsoap.org/soap/envelope/';
2. Receiving XML documents
Before processing an XML document with an XMLport, an XML stylesheet can be applied to remove namespaces. An XML stylesheet contains a language for transforming XML documents into other XML documents.
For example, the following procedure can be used in Navision:
RemoveNamespace(
XMLSourceDocument : Automation "'Microsoft XML, v4.0'.DOMDocument40";
VAR XMLDestinationDocument : Automation "'Microsoft XML, v4.0'.DOMDocument40")
TempTable."BLOB Field".CREATEOUTSTREAM(OutStreamStylesheet);
TempTable."BLOB Field".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(XMLDestinationDocument) THEN
CREATE(XMLDestinationDocument);
XMLSourceDocument.transformNodeToObject(XMLStyleSheet,XMLDestinationDocument);
Add the following C/AL Locals in the procedure:
TempTable: Record
OutStreamStylesheet: OutStream
InStreamStylesheet: InStream
XMLStyleSheet: Automation "'Microsoft XML, v4.0'.DOMDocument40"
"How do we give reference to the source xml file and where will the final xml file be generated"
Does anybody has any knowledge reagarding this?
Hi gupta.lalit
I had the same problem like everybody in this thread. I laboured a bit and find a possible way. Here is the solution with the Microsoft function that I use :
1. I have a form to fire the xmlPort.IMPORT
FILE example :
<DSKurz xmlns="http://tempuri.org/DSKurz.xsd">
<kurz>
<MENA>AUD</MENA>
<OD>2007-01-01T00:00:00+01:00</OD>
<DO>2999-12-31T23:59:59.997+01:00</DO>
<KURZ> 16.299</KURZ>
<POCET> 1</POCET>
<MIN_PLATN>2007-01-30T00:00:00+01:00</MIN_PLATN>
</kurz>
2. I put the Microsoft fcn to this form (I assume that you didn't have problem to implement it...)
3. The Code which fires the IMPORT is following :
XMLDocInput is 'Microsoft XML, v4.0'.DOMDocument40
XMLDocOut is 'Microsoft XML, v4.0'.DOMDocument40
DialogMgt is CU Common Dialog Management
// user chooses the xmlfile
ImportFileName := DialogMgt.OpenFile(ImpTitle,'',4,'XML (*.xml)|*.xml',0);
IF ImportFileName <> '' THEN BEGIN
// preparing the import xml document
IF ISCLEAR(XMLDocInput) THEN
CREATE(XMLDocInput);
XmlFile.OPEN(ImportFileName);
XmlFile.CREATEINSTREAM(XmlInStr);
// loading the import xml into the the XMLDOM
XMLDocInput.load(XmlInStr);
XmlFile.CLOSE;
// calling the Microsoft function
RemoveNamespace(XMLDocInput,XMLDocOut);
// Overwriting the import file with the transformed one
XMLDocOut.save(ImportFileName);
// Processing the transformed file the standard way
// Note, I use still the same file, however you can change the
// code, that you can save it to different one
XmlFile.OPEN(ImportFileName);
XmlFile.CREATEINSTREAM(XmlInStr);
XmlPortRateIn.SETSOURCE(XmlInStr);
XmlPortRateIn.IMPORT;
// clearing of course
XmlFile.CLOSE;
CLEAR(XMLDocOut);
CLEAR(XMLDocInput);
END;
Hopefully this will help you
One more add:
I found usefull, that you may keep the original file #-o , or you just simly don't have permissions to write [-X (most common).
You can change the code following way
...
RemoveNamespace(XMLDocInput,XMLDocOut);
TempImportTable.RESET;
TempImportTable.DELETEALL;
TempImportTable.Picture.CREATEOUTSTREAM(OutStrChangedFile);
TempImportTable.Picture.CREATEINSTREAM(InStrChangedFile);
XMLDocOut.save(OutStrChangedFile);
XmlPortRateIn.SETSOURCE(InStrChangedFile);
XmlPortRateIn.IMPORT;
...
The benefi is simple, you don't need to write to disk at all,
Enjoy !!!
Can u also tell me that what is the datatype and value of the following variables:
1) ImportFileName
2) ImpTitle
3)
// user chooses the xmlfile
ImportFileName := DialogMgt.OpenFile(ImpTitle,'',4,'XML (*.xml)|*.xml',0);
//
can you tell me what is 'XML(*.xml)|*.xml',0)'
4) XMLPortRateIn
5) TempImportTable
6) OutStrChangedFile
7) InStrChangedFile
8 ) TempTable - In RemovingNamespace function
1) ImportFileName type: Text1024
2) ImpTitle type:Text250
3) in this way you can set the filter (only XML-Files) in the Dialog Box
4) XMLPortRateIn type: XMLPort <your XML-Port>
5) TempImportTable type: Record (any table with a blob field, e.g. Table 27), property Temporary=Yes
6) OutStrChangedFile type: OutStream
7) InStrChangedFile type: InStream
8 ) see 5)
Hope this will help you.
I did it in this way - and it works fine
This has an advantage, if you have to read avery large file, that eats up your memory by using XMLDOM and BLOB, because it only reads 4 lines max.
Sorry, looks a bit wild. Does anyone know, how to keep tabstops?
PASS Multibank Solutions AG
(Kaum macht man was richtig, schon geht es. / Once you do it right, suddenly it works.)
This does not work properly with some ocasions!
like if you have following headers in xml file:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE Finvoice SYSTEM "Finvoice.dtd">
<?xml-stylesheet type="text/xsl" href="Finvoice.xsl"?>
<!--Finvoice xmlns:xsi="http://www.w3.org/2001/XMLScema-instance" xsi:noNamespaceSchemaLocation="c:/l/finvoice/finvoice.xsd"Version="1.2"-->
<Finvoice Version="1.2">...the rest of the file
if you run this through that remove namespaces function it clears the whole xml file leaving the new file 0KB, but if you leave that <!DOCTYPE Finvoice SYSTEM "Finvoice.dtd"> part out, it does not do anything for the file.
Is there any way I could clean the headings up to the first tag of the file?
<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="Finvoice.xsl"?>
<Finvoice Version="1.2">... the rest of the file
as this way the importing would work and I could use the xsl file for formating it.