LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

XML validating by XSD

hi all, we are looking for a possibility to validate a XML-file against a schema (xsd-file) inside CVI. is it possible to do this with fcts or tools comming with CVI ? If not: has anybody an idea how to do this - maybe by external libraries ? best regards Simon
0 Kudos
Message 1 of 8
(5,103 Views)
In CVI, you can do this using the MSXML DOM ActiveX server. First create an ActiveX controller for the latest version of "Microsoft XML" - I think one needs atleast MSXML 4.0 for this to work. Then use the following code (fixup the include file name and instrument prefix appropriately). The following code does not show error handling or cleanup to illustrate the core solution. This code is based on the MSDN code at: http://msdn2.microsoft.com/en-us/library/ms763722(VS.85).aspx
 
#include <ansi_c.h>
#include <msxml6.h>
 
static CAObjHandle LoadXMLDocument(const char *path)
{
 VBOOL success;
 CAObjHandle doc;
 VARIANT vtPath;
 
 MSXML2_NewDOMDocument40IXMLDOMDocument2(0, 0, LOCALE_NEUTRAL, 0, &doc);
 MSXML2_IXMLDOMDocument2Setasync(doc, 0, VFALSE);
 MSXML2_IXMLDOMDocument2SetvalidateOnParse(doc, 0, VFALSE);
 MSXML2_IXMLDOMDocument2SetresolveExternals(doc, 0, VFALSE);
 MSXML2_IXMLDOMDocument2SetpreserveWhiteSpace(doc, 0, VTRUE);
 CA_VariantSetCString(&vtPath, path);
 MSXML2_IXMLDOMDocument2load(doc, 0, vtPath, &success);
 assert(success == VTRUE);
 CA_VariantClear(&vtPath);
 return doc;
}
 
void main(void)
{
 long code;
 MSXML2Obj_IXMLDOMParseError err;
 CAObjHandle doc, schema, cache;
 VARIANT vt;
 
 doc = LoadXMLDocument("c:\\temp\\doc.xml");
 schema = LoadXMLDocument("c:\\temp\\schema.xsd");
 
 MSXML2_NewXMLSchemaCache40IXMLDOMSchemaCollection2(0, 0, LOCALE_NEUTRAL, 0, &cache);
 CA_VariantSetObjHandle(&vt, schema, CAVT_DISPATCH);
 MSXML2_IXMLDOMSchemaCollection2add(cache, 0, "urn:books", vt);
 CA_VariantClear(&vt);
 
 CA_VariantSetObjHandle(&vt, cache, CAVT_DISPATCH);
 MSXML2_IXMLDOMDocument2SetByRefschemas(doc, 0, vt);
 
 MSXML2_IXMLDOMDocument2validate(doc, 0, &err);
 MSXML2_IXMLDOMParseErrorGeterrorCode(err, 0, &code);
 if (code == 0)
 {
  puts("XML is valid");
 }
 else
 {
  char *desc;
  MSXML2_IXMLDOMParseErrorGetreason(err, 0, &desc);
  printf("XML is not valid because %s\n", desc);
 }
 
 getchar();
}
0 Kudos
Message 2 of 8
(5,092 Views)
mohan, thanks for reply. I tested the lines and it runs ok, but everytime I use this code the error-message is: "The root element has no DTD-file". but I dont want to use a dtd - which is an alternative methode to verify a XML-file (I think so). In the MSDN I saw a property of the XMLValicatingReader-Class (C#) called "ValidationType" and has to be set to "ValidationType.Schema". May be this is the cause ? best regards Simon
0 Kudos
Message 3 of 8
(5,052 Views)
I ran this with the XML and XSD files from the MSDN link in the previous post, and it ran fine without the DTD error. May be your XML file is referencing some DTD file or something? Or it could be a case of different MSXML DOM versions on our machines.
0 Kudos
Message 4 of 8
(5,041 Views)
mohan, dont know. I tested some validated XML/XSD-combinations and the result was the same - he asks for a DTD-file. so I looked for another solution and found one in the MSDN by using the COM-library. Attached the sources. I used some QT-classes to handle the strings, but think this is not a problem. best regards Simon
0 Kudos
Message 5 of 8
(5,011 Views)

Dear Mohan,

     I've compared your CVI code to the MSDN code at: http://msdn2.microsoft.com/en-us/library/ms763722(VS.85).aspx.

 

I've been able to match al your CVI code to the MSDN one with the exception of th MSDN code snippet for the function named "void ValidateDocumentNodes(IXMLDOMDocument3 *pDom, BSTR xpath)".

 

I'd like to write down the CVI counterpart of this C++ function but I'm not able to understand which are the CVI counterparts of the following C++ lines:

 

HRCALL(pDom->selectNodes(xpath,&pNodelist),"");
HRCALL(pNodelist->get_length(&length), "");
   ...

        HRCALL(pNodelist->get_item(i, &pNode), "");
        HRCALL(pDom->validateNode(pNode, &pError),"");
        ...
        HRCALL(pNode->get_nodeName(&bstr), "");
     
Could you kindly help me?

 

Thank you in advance.

0 Kudos
Message 6 of 8
(4,599 Views)

pDom->selectNodes            => MSXML_IXMLDOMDocument3selectNodes
pNodelist->get_length         => MSXML_IXMLDOMNodeListGetlength

pNodelist->get_item            => MSXML_IXMLDOMNodeListGetitem
pDom->validateNode          => MSXML_IXMLDOMDocument3validateNode

pNode->get_nodeName     => MSXML_IXMLDOMNodeGetnodeName

 

 The way to map is as follows. Consider pDom->selectNodes.

1) Find the type of pDom: IXMLDOMDocument3.

2) In CVI, open Instrument >> Microsoft XML and find the item corresponding to IXMLDOMDocument3. It will have the same name, IXMLDOMDocument3, unless you changed this during the wrapper generation or it was truncated for size reasons.

3) Now, in CVI, find the function under the IXMLDOMDocument3 item corresponding to the selectNodes method. It is, MSXML_IXMLDOMDocument3selectNodes.

4) In general, the naming scheme of the CVI generated function is <Instrument Prefix>_<Interface Name><Method Name>.

 

If you are not seeing these functions in the MSXML instrument (.fp) you have, then your file was generated with an older version of MSXML. You need to regenerate the ActiveX Controller wrapper for the latest version of MSXML on your system - I used version 5.0. You can do this in CVI using the Tools >> Create ActiveX Controller menu item.

 

0 Kudos
Message 7 of 8
(4,565 Views)

Dear Mohan,

 

 

     Thank you very much indeed for your hint, it do works.

 

Kind regards,

 

    Paolo

0 Kudos
Message 8 of 8
(4,526 Views)