Software solutions and questions blog
RSS icon Email icon Home icon
  • XSD en XML

    Posted on December 4th, 2008 Christophe No comments

    Ik zit al een tijdje te zwoegen op het inlezen van een XML bestand dat moet voldoen aan de normen van een XSD bestand.
    Ik doe dit in VB6.0

    Als ik mijn variabelen als volgt declareer :


    ' maak een referentie naar microsoft xml4.0 (project - references)
    ' declareer variabelen
    Dim sSchemaFile As String
    Dim sWorkFile As String
    sSchemaFile = txtSchemaPath.Text
    sWorkFile = txtPath.Text
    Dim schemaCache As MSXML2.XMLSchemaCache40
    Set schemaCache = New MSXML2.XMLSchemaCache40
    ' toevoegen van de namespace aan de schemacache
    schemaCache.Add "http://mijnnamespace.be/xml", sSchemaFile
    Dim xml_document As MSXML2.DOMDocument40
    Set xml_document = New MSXML2.DOMDocument40
    Set xml_document.Schemas = schemaCache

    Dan wordt de XML file getoetst door
    Set xml_document.Schemas = schemaCache

    Inlezen van het bestand in onze variabele:
    xml_document.async = False
    If Not xml_document.Load(sWorkFile) Then
    MsgBox "Error - : " & xml_document.parseError.reason
    Exit Sub
    End If

    Maar als ik nu een enkele node of een reeks nodes in een nodeobject wens in te lezen dan krijg ik steeds een ‘Nothing’ als return waarde.


    ' declareer node objecten
    Dim values_node As IXMLDOMNode ' single node
    Dim values_nodelist As IXMLDOMNodeList ' nodelijst (array)

    Set values_node = xml_document.SelectSingleNode("form//contactperson/name") --> Nothing
    Set values_node = xml_document.SelectSingleNode("form//contactperson/name") --> Nothing

    Ik heb de namespace dan toegevoegd aan de eigenschappen van het xml object (xml_document in mijn geval)

    xml_document.validateOnParse = True 'nodig vooraleer we de namespace property instellen
    xml_document.setProperty "SelectionNamespaces", "xmlns:x='http://mijnnamespace.be/xml'"

    We gebruiken x als prefix.

    Uitlezen:
    Set values_node = xml_document.SelectSingleNode("x:form//contactperson/nom") --> Nothing
    ' Attributen uitlezen:
    Set values_nodelist = xml_document.SelectNodes("x:form//@bedrag") --> array van bedragen

    (Tijdelijke) Work around om ook die single node uit te lezen.

    ' in plaats van naar domdocument40 te refereren:
    'Set xml_document.Schemas = schemaCache
    Set xml_document = New MSXML2.DOMDocument
    'Het xml_document valideren dmv de validate functie
    Validate sWorkFile, sSchemaFile

    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

    En dit werkt dus wel. Ook al vind ik het maar een beetje viesjes.

    Leave a reply