XML and Namespace - again!

tomadtomad Member Posts: 12
I am having problems importing an XML-file containing Namespaces into Navision (2.60 DB on 4.0 runtime). The import has worked fine until the namespaces was added to the file. I have searched this forum and found several entries on the subject, but i still lack some information, since XML-ports are new to me. I have decided the only way I can import the file is to use an XML Stylesheet to remove the namespaces and is therefore trying to implement the solution suggested by Microsoft (found in http://www.mibuso.com/forum/viewtopic.p ... hlight=xml). But when I add the procedure RemoveNamespace(XMLSourceDocument : Automation "'Microsoft XML, v4.0'.DOMDocument40"; VAR XMLDestinationDocument : Automation "'Microsoft XML, v4.0'.DOMDocument40"), I cannot figure out how to trigger the procedure - does anyone know which parameters should be added to "RemoveNamespace()" in my code?
Regards

/tomad

Comments

  • Anders_LidgrenAnders_Lidgren Member Posts: 19
    Hi

    Here you have a solution for this. Create a function which reads the XML-file.

    Function ReadXMLOrderFile()
    EDISetup.GET;
    EDISetup.TESTFIELD("Path Inbox");
    EDISetup.TESTFIELD(EDISetup."Filename XMLOrder");
    XMLFiles.SETRANGE("Is a file",TRUE);
    XMLFiles.SETRANGE(Path,'C:\'); // Force FileRec to look somewhere
    IF XMLFiles.FIND('-') THEN; // else, then back to your folder

    XMLFiles.SETRANGE(Path, EDISetup."Path Inbox");

    IF XMLFiles.FIND('-') THEN
    BEGIN
    CLEAR(XMLOrder);
    CLEAR(InputStream);
    CLEAR(XMLFile);
    CLEAR(SourceDocument);
    CLEAR(DestinationDocument);

    CREATE(SourceDocument);
    SourceDocument.async := FALSE;
    SourceDocument.load(EDISetup."Path Inbox" + XMLFiles.Name);
    CREATE(DestinationDocument);
    DestinationDocument.load(EDISetup."Path Inbox" + XMLFiles.Name);
    RemoveNamespace(SourceDocument,DestinationDocument,EDIInst."Path Inbox" +XMLFiles.Name);
    XMLFile.OPEN(EDIInst."Path Inbox" + XMLFiles.Name);
    XMLFile.CREATEINSTREAM(InputStream);
    XMLOrder.SETSOURCE(InputStream);
    XMLOrder.SetParameter(EDIInst."Path Inbox" + XMLFiles.Name);
    XMLOrder.IMPORT;
    XMLFile.CLOSE;
    RenameFile(EDIInst."Path Inbox",XMLFiles.Name);
    END;

    Function RemoveNamespace(XMLSourceDocument : Automation "'Microsoft XML, v4.0'.DOMDocument40";VAR XMLDestinationDocument : Automation "'Microsoft XML, v4.0'.DOMDocument40",Filename)

    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="@*&quot;>');
    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);
    XMLDestinationDocument.save(Filename);
    Anders Lidgren
    Navision Developer since 1998
    WM-data Sverige AB
  • astrid_kargerastrid_karger Member Posts: 1
    What I don't like in the Microsoft function is, that they use temporary tables. So I played a bit and here is my final code - without streams and tables, just the essence. I still don't understand how the transformation works, but it does - that's enough for me.

    The function has the following two parameters:
    XMLSourceDocumentP, Automation 'Microsoft XML, v4.0'.DOMDocument
    Var XMLDestinationDocumentP, Automation 'Microsoft XML, v4.0'.DOMDocument

    One local variable is also defined:
    XMLStyleSheetL, Automation 'Microsoft XML, v4.0'.DOMDocument
    RemoveNamespace(XMLSourceDocumentP : Automation "'Microsoft XML, v4.0'.DOMDocument";VAR XMLDestinationDocumentP : Automation "'Microsoft XML, v4.0'.DOMDocument")
    // before this function your tag looks like this: <namespace:tagname>sample text</tagname>
    // after this function your tag looks like this: <tagname>sample text</tagname>
    // additionally all namespace references in the head are removed.
    IF ISCLEAR(XMLStyleSheetL) THEN
      CREATE(XMLStyleSheetL);
    
    XMLStyleSheetL.loadXML(
    '<?xml version="1.0" encoding="UTF-8"?>' +
    '<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">' +
    '<xsl:output method="xml" encoding="UTF-8" />' +
    '<xsl:template match="/">' +
    '<xsl:copy>' +
    '<xsl:apply-templates />' +
    '</xsl:copy>' +
    '</xsl:template>' +
    '<xsl:template match="*">' +
    '<xsl:element name="{local-name()}">' +
    '<xsl:apply-templates select="@* | node()" />' +
    '</xsl:element>' +
    '</xsl:template>' +
    '<xsl:template match="@*">' +
    '<xsl:attribute name="{local-name()}"><xsl:value-of select="."/></xsl:attribute>' +
    '</xsl:template>' +
    '<xsl:template match="text() | processing-instruction() | comment()">' +
    '<xsl:copy />' +
    '</xsl:template>' +
    '</xsl:stylesheet>'
    );
    
    IF ISCLEAR(XMLDestinationDocumentP) THEN
      CREATE(XMLDestinationDocumentP);
    XMLSourceDocumentP.transformNodeToObject(XMLStyleSheetL,XMLDestinationDocumentP);
    


    Additional information:
    This should also work with the other XML Automations like DOMDocument40 and so on.

    And here is short code of how to use this function:

    The following variables have to be declared:
    XMLInL, Automation 'Microsoft XML, v4.0'.DOMDocument
    XMLResultL, Automation 'Microsoft XML, v4.0'.DOMDocument
    DialogWindowL, Codeunit Common Dialog Management (CU 412)
    FileNameL, Text[1024]
    IF ISCLEAR(XMLInL) THEN
      CREATE(XMLInL);
    
    FileNameL := DialogWindowL.OpenFile('Import XML-File', '*.xml', 1, '', 0);
    IF FileNameL = '' THEN
      EXIT;
    
    XMLInL.load(FileNameL);
    RemoveNamespace(XMLInP,XMLResultL)
    
    XMLResultL.save('C:\temp\new.xml');
    
Sign In or Register to comment.