Wim ten Brink
asked on
[XML] Validating with MSXML
Okay, for the current project I am working on I can only use the MSXML type library that I've imported from C:\WINNT\system32\msxml3.d ll and absolutely NOTHING ELSE! I am not looking for an alternative solution. I just need some functionality that works. Absolutely NO third-party components or libraries or whatever. Just a solution to get this code to work... (And I'm using Delphi 5 so don't start talking about the XML wizard of Delphi 7. I don't have any wizards and I don't need one either.)
Did you read the above? Fine. Here's the problem.
I have an XML file which needs to be validated. Thus I also have an XSD file that is linked to it. Basically, the XML file contains a list of topics, with several questions per topic and a possible answer per question. It looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="Documents.xslt"?>
<Document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocat ion="D:\XM L\Document s.xsd" LastUpdate="2004-11-12">
<TopicGroup Name="EE Example">
<Question Text="How to validate this file?">
<Answer>I don't know...</Answer>
</Question>
</TopicGroup>
</Document>
And yes, there's also a stylesheet connected to this file. The stylesheet is what I will use to extract some specific data from the XML file and turn it into a HTML file. Not interesting either...
Okay, the Delphi code I have is very limited in what it can use. Basically just the ActiveX unit and the MSXML type library. It has to read the XML file, validate it with the XSD file then translate it with the XSLT file. Piece of cake, except for the validation...
uses
Windows, SysUtils, ActiveX;
procedure TMyObject.Process;
var
DOMDocument: IXMLDOMDocument2;
HTMLDocument: IXMLDOMDocument2;
StyleSheet: IXMLDOMDocument2;
ParseError: IXMLDOMParseError;
begin
// First create the documents I need.
DOMDocument := CoDOMDocument.Create;
HTMLDocument := CoDOMDocument.Create;
StyleSheet := CoDOMDocument.Create;
// We want to validate during parsing.
DOMDocument.validateOnPars e := True;
// Load the XML file and the XSLT file.
DOMDocument.load( 'D:\XML\Documents.xml' );
StyleSheet.load( 'D:\XML\Documents.xslt' );
// See if we got an error.
ParseError := DOMDocument.parseError;
if ( ParseError.errorCode <> 0 ) then ReportError( ParseError.reason );
// For some reason, it went OK while I'm sure the XML file is NOT valid! (I made it invalid on purpose!)
// Alternative method:
ParseError := DOMDocument.validate;
if ( ParseError.errorCode <> 0 ) then ReportError( ParseError.reason );
// This just fails every time, saying: "Validate failed because the root element had no associated DTD/schema."
// Oh, well. Transform the darned thing.
HTMLDocument.loadXML( DOMDocument.transformNode( StyleSheet ) );
HTMLDocument.save( 'D:\CVS\NetLeo\Documents\D ocuments.h tml' );
// Well, that goes okay.
I know for sure the XML file is invalid yet MSXML claims it is not. (Or nags about the schema file.) Using XMLSpy, I made sure the contents of all files are as they should be. The schema and stylesheet are both valid and the XML file is just missing an attribute in one tag, making the rest valid.
If you're wondering what I'm trying to do here... I'm converting an XML file to XHTML here. Actually, there will be several transformations that I need to run on the XML file. Chances of invalid XML files is about 1 in 100, since sometimes, the process that generates the output gets killed before it has finished writing everything. (And in a rare occasion, it generates an invalid tag, but hey... I have no control over this other process.) My task is to make sure the file is valid (thus the schema) and then translate it. Preferably as fast as possible with a very small executable. Why? Because the executable will be located on a flash USB memory stick and the same stick will also have to contain the output file! (Yeah, it's a stupid method but hey... They only have to do this once per day so let them, okay?)
Maybe I should also load the Schema in an IXMLDOMDocument2 object and call some other function. Or whatever...
So, I can't spot my error. Who can?
Did you read the above? Fine. Here's the problem.
I have an XML file which needs to be validated. Thus I also have an XSD file that is linked to it. Basically, the XML file contains a list of topics, with several questions per topic and a possible answer per question. It looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="Documents.xslt"?>
<Document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocat
<TopicGroup Name="EE Example">
<Question Text="How to validate this file?">
<Answer>I don't know...</Answer>
</Question>
</TopicGroup>
</Document>
And yes, there's also a stylesheet connected to this file. The stylesheet is what I will use to extract some specific data from the XML file and turn it into a HTML file. Not interesting either...
Okay, the Delphi code I have is very limited in what it can use. Basically just the ActiveX unit and the MSXML type library. It has to read the XML file, validate it with the XSD file then translate it with the XSLT file. Piece of cake, except for the validation...
uses
Windows, SysUtils, ActiveX;
procedure TMyObject.Process;
var
DOMDocument: IXMLDOMDocument2;
HTMLDocument: IXMLDOMDocument2;
StyleSheet: IXMLDOMDocument2;
ParseError: IXMLDOMParseError;
begin
// First create the documents I need.
DOMDocument := CoDOMDocument.Create;
HTMLDocument := CoDOMDocument.Create;
StyleSheet := CoDOMDocument.Create;
// We want to validate during parsing.
DOMDocument.validateOnPars
// Load the XML file and the XSLT file.
DOMDocument.load( 'D:\XML\Documents.xml' );
StyleSheet.load( 'D:\XML\Documents.xslt' );
// See if we got an error.
ParseError := DOMDocument.parseError;
if ( ParseError.errorCode <> 0 ) then ReportError( ParseError.reason );
// For some reason, it went OK while I'm sure the XML file is NOT valid! (I made it invalid on purpose!)
// Alternative method:
ParseError := DOMDocument.validate;
if ( ParseError.errorCode <> 0 ) then ReportError( ParseError.reason );
// This just fails every time, saying: "Validate failed because the root element had no associated DTD/schema."
// Oh, well. Transform the darned thing.
HTMLDocument.loadXML( DOMDocument.transformNode(
HTMLDocument.save( 'D:\CVS\NetLeo\Documents\D
// Well, that goes okay.
I know for sure the XML file is invalid yet MSXML claims it is not. (Or nags about the schema file.) Using XMLSpy, I made sure the contents of all files are as they should be. The schema and stylesheet are both valid and the XML file is just missing an attribute in one tag, making the rest valid.
If you're wondering what I'm trying to do here... I'm converting an XML file to XHTML here. Actually, there will be several transformations that I need to run on the XML file. Chances of invalid XML files is about 1 in 100, since sometimes, the process that generates the output gets killed before it has finished writing everything. (And in a rare occasion, it generates an invalid tag, but hey... I have no control over this other process.) My task is to make sure the file is valid (thus the schema) and then translate it. Preferably as fast as possible with a very small executable. Why? Because the executable will be located on a flash USB memory stick and the same stick will also have to contain the output file! (Yeah, it's a stupid method but hey... They only have to do this once per day so let them, okay?)
Maybe I should also load the Schema in an IXMLDOMDocument2 object and call some other function. Or whatever...
So, I can't spot my error. Who can?
Don't you need to set the Async property to false before loading the XML from a file?
ASKER
Set it to false, no effect.
Btw. For the transformation I now use IXSLTemplate and IXSLProcessor which provide me a more powerful way to do the transformation. I'm looking for a similar solution for validations...
Btw. For the transformation I now use IXSLTemplate and IXSLProcessor which provide me a more powerful way to do the transformation. I'm looking for a similar solution for validations...
ASKER
Don't bother anymore. Solved the problem...
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
@RomMod,
I have left a message explaining that I found a solution and even provided the solution for future reference.
I wished the comment from BigRat had been of any use for me finding the solution but it wasn't even close. I am grateful for his attempt to try and help me though. But just being nice doesn't justify awarding points at EE...
I have left a message explaining that I found a solution and even provided the solution for future reference.
I wished the comment from BigRat had been of any use for me finding the solution but it wasn't even close. I am grateful for his attempt to try and help me though. But just being nice doesn't justify awarding points at EE...
>>I am grateful for his attempt to try and help me though.
... HER attempt....
No objections, RomMod.
... HER attempt....
No objections, RomMod.
ASKER
Her? Oops, my mistake. Couldn't see that from here... :-)