The MASM Forum

Projects => Poasm => Pelle's C compiler and tools => Topic started by: TimoVJL on April 17, 2025, 10:02:53 PM

Title: XmlLite reader test
Post by: TimoVJL on April 17, 2025, 10:02:53 PM
https://github.com/Frankie-PellesC/fSDK/blob/master/Samples_and_Tests/XML/Xml_Sample/xml_sample.c (https://github.com/Frankie-PellesC/fSDK/blob/master/Samples_and_Tests/XML/Xml_Sample/xml_sample.c)

This was just for header and lib testing:

Small XmlLite.dll test without any real node processing, just for testing Pelles C v13 rcs.
Full header and libs are found from fSDK site.

polib.exe -def:XmlLite.def -Out:XmlLite.lib
EDIT:
https://github.com/microsoft/Windows-classic-samples/blob/main/Samples/XmlLiteReader/cpp/XmlLiteReader.cpp (https://github.com/microsoft/Windows-classic-samples/blob/main/Samples/XmlLiteReader/cpp/XmlLiteReader.cpp)

EDIT: Just one function, so better to use dynamic loading
typedef int (WINAPI CREATEXMLREADER)(REFIID, void **, IMalloc *);
typedef CREATEXMLREADER *LCREATEXMLREADER;
HANDLE hLib;
static LCREATEXMLREADER CreateXmlReader;
hLib = LoadLibrary("xmllite.dll");
if (hLib)
CreateXmlReader = (LCREATEXMLREADER)GetProcAddress(hLib, "CreateXmlReader");
else return 1;
Title: Re: XmlLite reader test
Post by: guga on April 18, 2025, 03:14:00 AM
Perfect. Tks.
Title: Re: XmlLite reader test
Post by: guga on April 18, 2025, 03:17:39 AM
For Visual Studio to parse manifest files....

Note: In properties, under linker + Additional dependencies, need to include this: msxml6.lib, ole32.lib, oleaut32.lib

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <msxml6.h>
#include <stdio.h>
#include <objbase.h>

void HandleError(HRESULT hr, LPCWSTR message);
void DisplayNodeInfo(IXMLDOMNode* pNode);
HRESULT ParseXmlFile(LPCWSTR filename);

void HandleError(HRESULT hr, LPCWSTR message) {
    wprintf(L"Error: %s (0x%08X)\n", message, hr);
}

void DisplayNodeInfo(IXMLDOMNode* pNode) {
    BSTR nodeName = NULL;
    HRESULT hr = pNode->get_nodeName(&nodeName);
    if (SUCCEEDED(hr)) {
        if (nodeName) {
            wprintf(L"\nElement: %s\n", nodeName);
            SysFreeString(nodeName);
        }
    }

    // Get attributes
    IXMLDOMNamedNodeMap* pAttributes = NULL;
    hr = pNode->get_attributes(&pAttributes);
    if (SUCCEEDED(hr)) {
        long attrCount;
        pAttributes->get_length(&attrCount);

        for (long j = 0; j < attrCount; j++) {
            IXMLDOMNode* pAttrNode = NULL;
            hr = pAttributes->get_item(j, &pAttrNode);

            if (SUCCEEDED(hr) && pAttrNode) {
                BSTR attrName = NULL;
                VARIANT attrValue;
                VariantInit(&attrValue);

                hr = pAttrNode->get_nodeName(&attrName);
                if (SUCCEEDED(hr)) {
                    hr = pAttrNode->get_nodeValue(&attrValue);
                    if (SUCCEEDED(hr) && attrName && attrValue.vt == VT_BSTR) {
                        wprintf(L"  %s = %s\n", attrName, attrValue.bstrVal);
                    }
                    VariantClear(&attrValue);
                }
                if (attrName) SysFreeString(attrName);
                pAttrNode->Release();
            }
        }
        pAttributes->Release();
    }
}

HRESULT ParseXmlFile(LPCWSTR filename) {
    IXMLDOMDocument* pXMLDoc = NULL;
    IXMLDOMNodeList* pNodeList = NULL;
    HRESULT hr;

    // Create DOM document
    hr = CoCreateInstance(CLSID_DOMDocument60, NULL, CLSCTX_INPROC_SERVER,
        IID_IXMLDOMDocument, (void**)&pXMLDoc);
    if (FAILED(hr)) {
        HandleError(hr, L"Failed to create XML document object");
        return hr;
    }

    // Set async property to false
    VARIANT_BOOL varAsync = VARIANT_FALSE;
    pXMLDoc->put_async(varAsync);

    // Load XML file
    VARIANT varFileName;
    VariantInit(&varFileName);
    varFileName.vt = VT_BSTR;
    varFileName.bstrVal = SysAllocString(filename);

    VARIANT_BOOL varStatus;
    hr = pXMLDoc->load(varFileName, &varStatus);
    VariantClear(&varFileName);

    if (FAILED(hr)) {
        HandleError(hr, L"Failed to load XML file");
        pXMLDoc->Release();
        return hr;
    }
    if (varStatus != VARIANT_TRUE) {
        IXMLDOMParseError* pError = NULL;
        pXMLDoc->get_parseError(&pError);
        if (pError) {
            BSTR bstrReason = NULL;
            pError->get_reason(&bstrReason);
            wprintf(L"Parse Error: %s\n", bstrReason ? bstrReason : L"Unknown error");
            SysFreeString(bstrReason);
            pError->Release();
        }
        pXMLDoc->Release();
        return E_FAIL;
    }

    wprintf(L"\nSuccessfully loaded manifest file: %s\n", filename);

    // Query all elements to demonstrate parsing
    BSTR bstrQuery = SysAllocString(L"//*");
    hr = pXMLDoc->selectNodes(bstrQuery, &pNodeList);
    SysFreeString(bstrQuery);

    if (FAILED(hr)) {
        HandleError(hr, L"Failed to select nodes");
        pXMLDoc->Release();
        return hr;
    }

    long nodeCount;
    hr = pNodeList->get_length(&nodeCount);
    if (FAILED(hr)) {
        HandleError(hr, L"Failed to get node count");
        pNodeList->Release();
        pXMLDoc->Release();
        return hr;
    }

    wprintf(L"\nFound %d elements in manifest:\n", nodeCount);

    // Process each node
    for (long i = 0; i < nodeCount; i++) {
        IXMLDOMNode* pNode = NULL;
        hr = pNodeList->get_item(i, &pNode);
        if (SUCCEEDED(hr) && pNode) {
            DisplayNodeInfo(pNode);
            pNode->Release();
        }
    }

    // Specific query for assemblyIdentity elements
    bstrQuery = SysAllocString(L"//assemblyIdentity");
    hr = pXMLDoc->selectNodes(bstrQuery, &pNodeList);
    SysFreeString(bstrQuery);

    if (SUCCEEDED(hr)) {
        hr = pNodeList->get_length(&nodeCount);
        if (SUCCEEDED(hr) && nodeCount > 0) {
            wprintf(L"\nFound %d assemblyIdentity elements:\n", nodeCount);
            for (long i = 0; i < nodeCount; i++) {
                IXMLDOMNode* pNode = NULL;
                hr = pNodeList->get_item(i, &pNode);
                if (SUCCEEDED(hr) && pNode) {
                    DisplayNodeInfo(pNode);
                    pNode->Release();
                }
            }
        }
        pNodeList->Release();
    }

    // Specific query for requestedExecutionLevel
    bstrQuery = SysAllocString(L"//requestedExecutionLevel");
    hr = pXMLDoc->selectNodes(bstrQuery, &pNodeList);
    SysFreeString(bstrQuery);

    if (SUCCEEDED(hr)) {
        hr = pNodeList->get_length(&nodeCount);
        if (SUCCEEDED(hr) && nodeCount > 0) {
            wprintf(L"\nFound %d requestedExecutionLevel elements:\n", nodeCount);
            for (long i = 0; i < nodeCount; i++) {
                IXMLDOMNode* pNode = NULL;
                hr = pNodeList->get_item(i, &pNode);
                if (SUCCEEDED(hr) && pNode) {
                    DisplayNodeInfo(pNode);
                    pNode->Release();
                }
            }
        }
        pNodeList->Release();
    }

    pXMLDoc->Release();
    return S_OK;
}

int wmain(int argc, WCHAR* argv[]) {
    if (argc < 2) {
        wprintf(L"Usage: %s <manifest_file.xml>\n", argv[0]);
        return 1;
    }

    HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
    if (FAILED(hr)) {
        HandleError(hr, L"CoInitializeEx failed");
        return 1;
    }

    hr = ParseXmlFile(argv[1]);
    if (FAILED(hr)) {
        wprintf(L"Failed to parse XML file (HRESULT: 0x%08X)\n", hr);
    }

    CoUninitialize();
    return 0;
}
Title: Re: XmlLite reader test
Post by: TimoVJL on April 18, 2025, 04:29:30 AM
https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms753140(v=vs.85) (https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms753140(v=vs.85))
Xmllite is for C++ and other languages, and it is LWCOM.
It used normal UNICODE string, so easier to use.
With dynamic loading it don't need import library.
Those def-files was for testing polib.exe for creating libraries.