VB6: Validate XML against XSD in Visual Basic

http://www.nonhostile.com/howto-validate-xml-xsd-in-vb6.asp

 

 

 

 

This code requires a project reference to Microsoft XML 4.0 available from Microsoft's Download Center

This is a very simple example to demostrate the validation of a fragment of XML.
We want a validate than a element called sampleRoot has an attribute called myAttribute that can have a value of either 'animal', 'vegatable' or 'mineral'.

Sample XSD
This XSD defines our schema. We have to give it a namespace, for this example we're using urn:sample
    <!-- two namespaces used, xsd schema and the one we're defining (targetNamespace) -->
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
               xmlns:n="urn:sample"
               targetNamespace="urn:sample">
       
      <!-- define root element -->
      <xs:element name="sampleRoot" type="n:sampleRootType"/>
     
      <!-- define a datatype: sampleRootType -->
      <xs:complexType name="sampleRootType">
        <xs:attribute name="myAttribute" type="n:AnimalVegMineral" use="optional"/>
      </xs:complexType>
     
      <!-- define a Animal/Veg/Mineral data type -->
      <xs:simpleType name="AnimalVegMineral">
        <xs:restriction base="xs:string">
          <xs:enumeration value="animal"/>
          <xs:enumeration value="vegatable"/>
          <xs:enumeration value="mineral"/>
        </xs:restriction>
      </xs:simpleType>

    </xs:schema>

Samples of XML that Reference Our Schema Definition
XML documents that should conform to this schema must declare their namespace. The following fragments conform to the bove schema definition:
    <x:sampleRoot xmlns:x="urn:sample" myAttribute="animal"/>
The following fragments do not.
    <x:sampleRoot xmlns:x="urn:sample" myAttribute="piano"/>
Visual Basic Code to Validate an XML File against an XSD File
This function accepts the paths of two datafiles. An XML Schema Definition and an XML file.

    Private Function Validate(ByVal strXMLPath As String, _
                              ByVal strXSDPath As String) As Boolean

        Dim objSchemas As MSXML2.XMLSchemaCache40
        Dim objXML As MSXML2.DOMDocument40
        Dim objXSD As MSXML2.DOMDocument40
        Dim strNamespace As String
        Dim objErr As MSXML2.IXMLDOMParseError
       
        ' load XSD as DOM to populate in Schema Cache
        Set objXSD = New MSXML2.DOMDocument40
        objXSD.async = False
        If Not objXSD.Load(strXSDPath) Then
            Err.Raise 1, "Validate", "Load XSD failed: " & objXSD.parseError.reason
        Else
            ' get namespace name from XSD targetNamespace attribute
            strNamespace = objXSD.documentElement.getAttribute("targetNamespace")
        End If
       
        ' populate schema cache
        Set objSchemas = New MSXML2.XMLSchemaCache40
        objSchemas.Add strNamespace, objXSD
       
        ' load XML file (without validation - that comes later)
        Set objXML = New MSXML2.DOMDocument40
        objXML.async = False
        objXML.validateOnParse = False
        objXML.resolveExternals = False
       
        ' load XML, without any validation
        If Not objXML.Load(strXMLPath) Then
            Err.Raise 1, "Validate", "Load XML failed: " & objXML.parseError.reason
        End If
       
        ' bind Schema Cache to DOM
        Set objXML.schemas = objSchemas
       
        ' does this XML measure up?
        Set objErr = objXML.Validate()
       
        ' any good?
        Validate = (objErr.errorCode = 0)
        If objErr.errorCode <> 0 Then
            Err.Raise 1, "Validate", objErr.reason
        End If

    End Function

The above function could easily be adapted to load XML and XSD from string variables as opposed to data files.

For situations where multiple XML validations are required, repeatedly populating and destroying the schema cache is clearly ineffecient and could be optimised.

Examples Calling this Function
    Validate App.Path & "\sc-valid-tjh.xml", App.Path & "\sc-tjh-min.xsd"
    Validate App.Path & "\sc-valid.xml", App.Path & "\sc-tjh-min.xsd"
<script type="text/javascript">// <![CDATA[ google_ad_client = "pub-0974635012543471"; google_ad_width = 728; google_ad_height = 90; google_ad_format = "728x90_as"; google_ad_type = "text"; google_ad_channel =""; google_color_border = "DCDCDC"; google_color_bg = "F5F5F5"; google_color_link = "000080"; google_color_url = "008000"; google_color_text = "000000"; // ]]></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>

468 comments, Visual Basic 6, Thursday, April 15, 2004 16:24


 

Timeline Navigation for Visual Basic 6 posts
VB6: Convert HTML into Searchable Text using Regular Expressions (made 3 weeks later)
VB6: Validate XML against XSD in Visual Basic (this post, made Thursday, April 15, 2004 16:24)
VB6: Read XML from a Visual Basic Resource and Return Root Element (made 52 minutes earlier)


 

Comments
Hi,

I have a question: I've tried implementing this code with MSXML6 (replacing the 40's with 60's) and I have the follwing problem,

if the XML file has the declaration:

<fb:pratiche xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.fbk.it/pratiche file:///w:/xml/xsd/pratiche/Master.xsd" xmlns:fb=" http://www.fbk.it/pratiche">

it refuses to validate saying :
error 1072897500 - "The node is niether valid nor invalid because no DTD/Schema declaration was found"

however, if I remove the xsi namespace, it works perfectly.

Do you have any idea what might be causing this?

Posted by: nick brandwood on Monday, March 6, 2006 16:19

Posted by: zisco on Wednesday, January 3, 2007 15:57
how we can puts check on email address whter an email address is valid or invalid?

Posted by: syed on Tuesday, August 14, 2007 12:05
Hi,

This example is a good help. Thanks.

I only had the following problem :

' does this XML measure up?
Set objErr = objXML.Validate()

If objErr.errorCode <> 0 Then
' worked fine
Debug.Print "errorCode " & objErr.errorCode
Debug.Print "reason " & objErr.reason

' I didn't manage to get following information
Debug.Print "filepos " & objErr.filepos
Debug.Print "Line " & objErr.Line
Debug.Print "linepos " & objErr.linepos
Debug.Print "srcText " & objErr.srcText
Debug.Print "url " & objErr.url
end if


Then I tried following code :

objXML.async = False
objXML.validateOnParse = True
objXML.resolveExternals = True

If Not objXML.Load(strXMLPath) Then
' In this case I could get the information from every member
Debug.Print "errorCode " & objXML.parseError.errorCode
Debug.Print "reason " & objXML.parseError.reason
Debug.Print "filepos " & objXML.parseError.filepos
Debug.Print "Line " & objXML.parseError.Line
Debug.Print "linepos " & objXML.parseError.linepos
Debug.Print "srcText " & objXML.parseError.srcText
Debug.Print "url " & objXML.parseError.url
end if

I don't understand, why it is like that. But you might have an answer.


P.S : objXML.resolveExternals = True solves the problem with MSXML6



Posted by: odCaplan on Monday, September 3, 2007 08:17
I also use the dll file msxml6.dll but I get the error:
error 1072897500 - "The node is niether valid nor invalid because no DTD/Schema declaration was found"

The beginning of the xsd file looks like:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="Tmp" targetNamespace="urn:Tmp.xsd" xmlns:mstns="urn:Tmp.xsd" xmlns="urn:Tmp.xsd" xmlns:xs=" http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:msprop="urn:schemas-microsoft-com:xml-msprop" attributeFormDefault="qualified" elementFormDefault="qualified">

Does anyone know what the problem is?

Posted by: Mark on Thursday, April 17, 2008 15:22
Hi,

I've used your VB code on a project I'm working on and it works perfectly. Thank you.
At the moment, if I validate an XML file with more than one error, the function returns a message detailing the error found.
Would it be possible to modify this code so that the validation process continues on after the first error is found and returns a message detailing all errors found?
e.g.
Error parsing '2008-13-07' as date datatype.
The element: '{urn:iso:std:iso:20022:tech:xsd:pacs.008.001.01}IntrBkSttlmDt' has an invalid value according to its data type.
Error parsing '2360.0q' as decimal datatype.
The element: '{urn:iso:std:iso:20022:tech:xsd:pacs.008.001.01}IntrBkSttlmAmt' has an invalid value according to its data type.

Thanks in advance.


Posted by: Shaymoh on Friday, June 6, 2008 13:34
Did anyone have a solution of detecting all errors in one shot?

Posted by: Mike on Wednesday, January 14, 2009 21:54
great post, thanks!

Posted by: Ken on Wednesday, February 25, 2009 16:54
I found some code that loads all errors into an Array.

http://forums.devx.com/archive/index.php/t-136153.html


Posted by: Chris on Friday, March 20, 2009 18:26
The url given by Chris is for VB.net code, not VB6 -I think.

Posted by: IsabelG on Wednesday, July 8, 2009 08:25
How can i load xml file into datagrid in vb6...Please help

Posted by: saurabh on Wednesday, August 12, 2009 07:12
Thanks. These codes work successfully. I need another help. Is it possible to write xml with vb6.0 with a specified schema? If possible, then how?
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值