Microsoft KB Archive/315504

= PRB: MSXML 4.0 SAX Parser Raises Error Event Before startElement Event =

Article ID: 315504

Article Last Modified on 4/12/2002

-

APPLIES TO


 * Microsoft XML Core Services 4.0

-



This article was previously published under Q315504



SYMPTOMS
When you use the MSXML 4.0 Simple API for XML (SAX) parser to validate an element that contains an attribute that is not valid (for example, if the attribute is not defined in the schema, or the attribute contains a value that is not valid), the SAX parser raises the error event of ISAXErrorHandler (IVBSAXErrorHandler) before the parser raises the startElement event of ISAXContentHandler (IVBSAXContentHandler). When the SAX parser raises the error event, only the line number and column number information that is associated with ISAXLocator is available to identify the faulty attribute, instead of the element name that contains the attribute.



CAUSE
Before the MSXML SAX parser fires the startElement event, the parser parses and validates the attributes on the element, builds the ISAXAttributes attribute collection, and then passes the ISAXAttributes attribute collection as an input parameter to the SAX ContentHandler interface (ISAXContentHandler::startElement), as follows: HRESULT STDMETHODCALLTYPE ISAXContentHandler::startElement(            /* [in] */ wchar_t __RPC_FAR *pwchNamespaceUri,            /* [in] */ int cchNamespaceUri,            /* [in] */ wchar_t __RPC_FAR *pwchLocalName,            /* [in] */ int cchLocalName,            /* [in] */ wchar_t __RPC_FAR *pwchRawName,            /* [in] */ int cchRawName,            /* [in] */ ISAXAttributes __RPC_FAR *pAttributes) If a validation error occurs on the attribute, the SAX parser raises the error event before the parser fires the startElement event.



RESOLUTION
To work around this problem, identify the name of the XML element that contains an attribute or attribute value that is not valid when you use the SAX validation feature in MSXML 4.0. To do this, either use the line number and column number information that the parser returns to identify the faulty attribute, or use the following method:
 * 1) Trap and store the SAX validation error code that the SAX parser generates when the parser finds an attribute or attribute value that is not valid in a global variable in the IVBSAXErrorHandler_error procedure.NOTE: In the October 2001 RTM release of MSXML 4.0, this error code is -2147467259.


 * 1) Check the global variable for the error code in the IVBSAXContentHandler_startElement event procedure that the SAX parser fires afterward to determine whether the element that the parser parses contains an attribute or attribute value that is not valid.
 * 2) Use the strQName or strLocalName parameters that the parser passes to the IVBSAXContentHandler_startElement event to determine the name of the XML element when the conditional check for the error code for the attribute or attribute value that is not valid evaluates to TRUE.
 * 3) Clear the global variable each time the check for the error code for the attribute or attribute value that is not valid evaluates to TRUE.



STATUS
This behavior is by design.



MORE INFORMATION
With the MSXML 4.0 release, the SAX parser only supports validation against XML Schema Definition (XSD) schema. Document Type Definition (DTD) and XML-Data Reduced (XDR) schema validation are not supported in this release.

Steps to Reproduce Behavior
  Use the following XML schema definition to create and save an XSD schema document named Person.xsd in the root folder of your hard disk: 



    

  <xs:element name=&quot;Name&quot; type=&quot;xs:string&quot;/> </xs:sequence> <xs:attribute name=&quot;age&quot; type=&quot;xs:integer&quot; use=&quot;required&quot;/> </xs:complexType>

</xs:schema> </li> <li> Use the following XML to create and save an XML document named Person.xml in the root folder of your hard disk: <?xml version=&quot;1.0&quot;?> <People xmlns=&quot;xsdPerson&quot; xsi:schemaLocation='xsdPerson person.xsd' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'> <Person age=&quot;28&quot; rank=&quot;1&quot;> <Name>Sam</Name> </Person> </People> NOTE: The   element in Person.xml has an attribute that is not valid. The rank attribute has not been defined as an attribute of the   element in the schema document.

</li> <li>In Microsoft Visual Basic 6.0, create a new Standard EXE project.</li> <li>Add a project reference to Microsoft XML, v4.0.</li> <li>Add a class module to the Visual Basic project and name it SAXValidator. This class module is used to implement the IVBSAXErrorHandler interface to trap and report errors that the parser finds when you parse and validate an XML document.</li> <li> Paste the following code in the SAXValidator class module: Implements MSXML2.IVBSAXErrorHandler

Private Sub IVBSAXErrorHandler_error(ByVal oLocator As MSXML2.IVBSAXLocator, strErrorMessage As String, ByVal nErrorCode As Long) Debug.Print nErrorCode & &quot; : &quot; & strErrorMessage & &quot; Line : &quot; & oLocator.lineNumber End Sub

Private Sub IVBSAXErrorHandler_fatalError(ByVal oLocator As MSXML2.IVBSAXLocator, strErrorMessage As String, ByVal nErrorCode As Long) Debug.Print nErrorCode & &quot; : &quot; & strErrorMessage & &quot; Line : &quot; & oLocator.lineNumber End Sub

Private Sub IVBSAXErrorHandler_ignorableWarning(ByVal oLocator As MSXML2.IVBSAXLocator, strErrorMessage As String, ByVal nErrorCode As Long)

End Sub </li> <li>Add a class module to the Visual Basic project and name it SAXContentHandler. This class module is used to implement the IVBSAXContentHandler interface.</li> <li> Paste the following code in the SAXContentHandler class module. Note that only the IVBSAXContentHandler_startElement procedure contains code to report the occurrences of the startElement event: Implements MSXML2.IVBSAXContentHandler

Private Sub IVBSAXContentHandler_characters(strChars As String)

End Sub

Private Property Set IVBSAXContentHandler_documentLocator(ByVal RHS As MSXML2.IVBSAXLocator)

End Property

Private Sub IVBSAXContentHandler_endDocument

End Sub

Private Sub IVBSAXContentHandler_endElement(strNamespaceURI As String, strLocalName As String, strQName As String)

End Sub

Private Sub IVBSAXContentHandler_endPrefixMapping(strPrefix As String)

End Sub

Private Sub IVBSAXContentHandler_ignorableWhitespace(strChars As String)

End Sub

Private Sub IVBSAXContentHandler_processingInstruction(strTarget As String, strData As String)

End Sub

Private Sub IVBSAXContentHandler_skippedEntity(strName As String)

End Sub

Private Sub IVBSAXContentHandler_startDocument

End Sub

Private Sub IVBSAXContentHandler_startElement(strNamespaceURI As String, strLocalName As String, strQName As String, ByVal oAttributes As MSXML2.IVBSAXAttributes) Debug.Print &quot;Start Element : &quot; & strQName End Sub

Private Sub IVBSAXContentHandler_startPrefixMapping(strPrefix As String, strURI As String)

End Sub </li> <li>Drag a CommandButton control onto Form1.</li> <li> Paste the following code in the Click event procedure of the CommandButton control to use Person.xsd to parse and validate Person.xml:NOTE: Modify the paths to the documents if you saved them in a different location. Dim rdr As New MSXML2.SAXXMLReader40 Dim Validator As New SAXValidator Dim chandler As New SAXContentHandler Dim sc As New MSXML2.XMLSchemaCache40

sc.Add &quot;xsdPerson&quot;, &quot;c:\person.xml&quot;

rdr.putFeature &quot;schema-validation&quot;, True rdr.putFeature &quot;exhaustive-errors&quot;, True rdr.putProperty &quot;schemas&quot;, sc

Set rdr.contentHandler = chandler Set rdr.errorHandler = Validator

rdr.parseURL &quot;c:\person.xml&quot;

</li> <li> Execute the project, and then click the command button when the form appears. The following output appears in the Visual Basic Immediate window: Start Element : People -2147467259 : The attribute 'rank' on this element is not defined in the DTD/Schema. Line : 3 Start Element : Person Start Element : Name The output indicates that when the parser parses the <Person> element and reports the undefined rank attribute for the <Person> element, the parser executes the code in the IVBSAXErrorHandler_error procedure in the SAXValidator class module before the parser executes the code in the IVBSAXContentHandler_startElement procedure in the SAXContentHandler class module. </li></ol>

Keywords: kbprb KB315504

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.