LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

CVI 7.1.1 how to add Tabulation in generated CVIXML file

Hi,
 
I use CVI 7.1.1 and CVIXML library to generate xml files.
But the generated file doesn't fave tabulation character and look like this :
 

<?xml version="1.0"?>
<tag XML1>
<child tag xml 1>
..
</child tag xml1>
</tag XML 1>

I want this :
 

<?xml version="1.0"?>
<tag XML1>
     <child tag xml 1>
..
</child tag xml1>
</tag XML 1>

I use This functions : 
CVIXMLNewDocument,
CVIXMLGetRoot
CVIXMLNewElement
CVIXMLAddAttribute .....
 
Thanks.
 
 


Message Edité par lio33 le 01-31-2008 08:30 AM
0 Kudos
Message 1 of 3
(4,434 Views)
Formatting and indenting XML is generally not recommended as this can interfere with computer to computer communication of XML. Formatting and indentation is only for human readers and this should generally be handled by the XML editor you use. Notepad, etc will not  provide any formatting or indentation but you can use even IE to look at the XML with formatting.

The CVIXML code uses the MSXML DOM. MSXML DOM does not support indenting or formatting the saved XML. The formatting in CVIXMLSaveDocument is actually done outside of MSXML DOM and only supports inserting newline between elements. For indentation, there are a number of approaches, but the simplest and best seems to be using SAX and MXXMLWriter. This requires a newer version of MSXML ActiveX wrapper than the one used by CVIXML - I generated wrappers for MSXML 5.0 as msxml2.fp and used this in the following code. Other approaches to indentation include using the .NET XmlWriter, style-sheet transformations using XSLT, etc.

#include <msxml2.h> /* NOTE - activex controller for MSXML 5.0 */
#include <cvixml.h>
#include <ansi_c.h>

#define XML_FILE_PATH    "c:\\temp\\temp.xml"
#define XML_FILE_PATH2    L"c:\\temp\\temp.xml"

static void CreateXML(void)
{
    CVIXMLElement elem1 = 0, elem2 = 0, elem3 = 0;
    CVIXMLDocument doc = 0;
    CVIXMLStatus error;
   
    errChk(CVIXMLNewDocument("first", &doc));
    errChk(CVIXMLGetRootElement(doc, &elem1));
    errChk(CVIXMLNewElement(elem1, -1, "second", &elem2));
    errChk(CVIXMLNewElement(elem2, -1, "third", &elem3));
    /* NOTE - do not save with formatting */
    errChk(CVIXMLSaveDocument(doc, 0, XML_FILE_PATH));

Error:
    CVIXMLDiscardElement(elem1);
    CVIXMLDiscardElement(elem2);
    CVIXMLDiscardElement(elem3);
    CVIXMLDiscardDocument(doc);
    if (error < 0)
    {
        char errorBuffer[512];
        CVIXMLGetErrorString(error, errorBuffer, sizeof(errorBuffer) - 1);
        fprintf(stderr, "Error: %s\n", errorBuffer);
    }
}

static void IndentXML(void)
{
    FILE *outputFile = 0;
    char *output = 0;
    VARIANT vtOutput, vtWriter;
    CAObjHandle writer = 0;
    CAObjHandle reader = 0;
    HRESULT error;
   
    CA_VariantSetEmpty(&vtOutput);
    CA_VariantSetEmpty(&vtWriter);
   
    errChk(MSXML2_NewSAXXMLReaderISAXXMLReader(NULL, 1, LOCALE_NEUTRAL, 0, &reader));
    errChk(MSXML2_NewMXXMLWriterIMXWriter(NULL, 1, LOCALE_NEUTRAL, 0, &writer));
    errChk(MSXML2_IMXWriterSetindent(writer, NULL, VTRUE));
    errChk(MSXML2_IMXWriterSetstandalone(writer, NULL, VTRUE));
    errChk(MSXML2_ISAXXMLReaderputContentHandler(reader, NULL, writer));
    errChk(CA_VariantSetObjHandle(&vtWriter, writer, CAVT_UNKNOWN));
    errChk(MSXML2_ISAXXMLReaderputProperty(reader, NULL,
        L"http://xml.org/sax/properties/lexical-handler", vtWriter));
    errChk(MSXML2_ISAXXMLReaderparseURL(reader, NULL, (unsigned short *)XML_FILE_PATH2));
    errChk(MSXML2_IMXWriterGetoutput(writer, NULL, &vtOutput));
    errChk(CA_VariantGetCString(&vtOutput, &output));
    nullChk(outputFile = fopen(XML_FILE_PATH, "w"));
    fwrite(output, sizeof(*output), strlen(output), outputFile);

Error:
    fclose(outputFile);
    CA_DiscardObjHandle(reader);
    CA_DiscardObjHandle(writer);
    CA_FreeMemory(output);
    CA_VariantClear(&vtOutput);
    CA_VariantClear(&vtWriter);
    if (FAILED(error))
    {
        char errorBuffer[512];
        CA_GetAutomationErrorString(error, errorBuffer, sizeof(errorBuffer) - 1);
        fprintf(stderr, "Error: %s\n", errorBuffer);
    }
}

void main(void)
{
    CreateXML();
    IndentXML();
}

0 Kudos
Message 2 of 3
(4,418 Views)

In the above IndentXML function, there are two problems.

1) The file must be opened in binary mode.

2) It seems that the IMXWriter output always has UTF-16 encoding. This can be incorrect. So it is better to remove the XML header line ("<?xml ...?>") or replace it with one's own.

The following is a modified better version:

static void IndentXML(void)
{
    FILE *outputFile = 0;
    char *output = 0, *out;
    VARIANT vtOutput, vtWriter;
    CAObjHandle writer = 0;
    CAObjHandle reader = 0;
    HRESULT error;
   
    CA_VariantSetEmpty(&vtOutput);
    CA_VariantSetEmpty(&vtWriter);
   
    errChk(MSXML2_NewSAXXMLReaderISAXXMLReader(NULL, 1, LOCALE_NEUTRAL, 0, &reader));
    errChk(MSXML2_NewMXXMLWriterIMXWriter(NULL, 1, LOCALE_NEUTRAL, 0, &writer));
    errChk(MSXML2_IMXWriterSetindent(writer, NULL, VTRUE));
    errChk(MSXML2_IMXWriterSetstandalone(writer, NULL, VTRUE));
    errChk(MSXML2_ISAXXMLReaderputContentHandler(reader, NULL, writer));
    errChk(CA_VariantSetObjHandle(&vtWriter, writer, CAVT_UNKNOWN));
    errChk(MSXML2_ISAXXMLReaderputProperty(reader, NULL,
        L"
http://xml.org/sax/properties/lexical-handler", vtWriter));
    errChk(MSXML2_ISAXXMLReaderparseURL(reader, NULL, (unsigned short *)XML_FILE_PATH));
    errChk(MSXML2_IMXWriterGetoutput(writer, NULL, &vtOutput));
    errChk(CA_VariantGetCString(&vtOutput, &output));
    nullChk(outputFile = fopen(XML_FILE_PATH, "wb"));
    out = strstr(output, "\r\n");
    out += 2;
    fwrite(out, sizeof(char), strlen(out), outputFile);

Error:
    if (outputFile)
        fclose(outputFile);
    CA_DiscardObjHandle(reader);
    CA_DiscardObjHandle(writer);
    CA_FreeMemory(output);
    CA_VariantClear(&vtOutput);
    CA_VariantClear(&vtWriter);
    if (FAILED(error))
    {
        char errorBuffer[512];
        CA_GetAutomationErrorString(error, errorBuffer, sizeof(errorBuffer) - 1);
        fprintf(stderr, "Error: %s\n", errorBuffer);
    }
}

0 Kudos
Message 3 of 3
(4,266 Views)