libxml external dtd
BlitzMax Forums/Brucey's Modules/libxml external dtd
| ||
Hi. I have some xml files which need to be validated with a seperate dtd file, but I can't get libxml to validate them correctly despite trying many variations. Here's the code I'm using to validate:Function validate:Int(filename:String) Local reader:TxmlTextReader = TxmlTextReader.fromFile(filename) reader.setParserProp(3, 1) Local ret = reader.read() While ret = 1 ret = reader.read() Wend reader.free() If ret <> 0 Then RuntimeError "Error validating " + filename Return False End If Return True End Function This is world.dtd <!ELEMENT world (entities, players)> <!ELEMENT entities (object*)> <!ELEMENT object EMPTY> <!ELEMENT players (player*)> <!ELEMENT player EMPTY> <!ATTLIST world x CDATA #REQUIRED> <!ATTLIST world y CDATA #REQUIRED> <!ATTLIST world background CDATA #REQUIRED> <!ATTLIST object name CDATA #REQUIRED> <!ATTLIST object x CDATA #REQUIRED> <!ATTLIST object y CDATA #REQUIRED> <!ATTLIST object angle CDATA "-1"> <!ATTLIST object player CDATA #IMPLIED> <!ATTLIST player id CDATA #REQUIRED> <!ATTLIST player money CDATA #REQUIRED> <!ATTLIST player view_x CDATA #REQUIRED> <!ATTLIST player view_y CDATA #REQUIRED> This is a sample xml file <!DOCTYPE world SYSTEM "world.dtd"> <world x="10000" y="10000" background="..\Data\Graphics\Scenery\Background\Grass1.png"> <entities> <object name="Scenery:Rock" x="50" y="50" /> <object name="Scenery:Stone" x="250" y="50" /> <object name="Scenery:Tree" x="5000" y="2500" /> <object name="Scenery:Tree" x="5500" y="4500" /> <object name="Scenery:Tree" x="6060" y="2550" /> <object name="Scenery:Tree" x="4050" y="2350" /> <object name="Turret:Cannon" x="250" y="2850" angle="50" player="1" /> </entities> <players> <player id="1" money="300" view_x="100" view_y="100" /> </players> </world> If I place the dtd inline with the xml file, it works and validates perfectly. If I put it in a seperate file (in the same folder) it allows anything to work. Remove the x and y from world and it will still load for example. |
| ||
I've tried various things, and it always works as I'd expect. If I change the sample.xml : <object name="Scenery:Stone"/><!-- x="250" y="50" /--> I get this output : sample.xml:6: element object: validity error : Element object does not carry attribute y <object name="Scenery:Stone"/><!-- x="250" y="50" /--> ^ sample.xml:6: element object: validity error : Element object does not carry attribute x <object name="Scenery:Stone"/><!-- x="250" y="50" /--> which is correct. If I rename the world.dtd file, I get this output : sample.xml:1: I/O error : failed to load external entity "world.dtd" <!DOCTYPE world SYSTEM "world.dtd"> ^ sample.xml:3: validity error : Validation failed: no DTD found ! x="10000" y="10000" background="..\Data\Graphics\Scenery\Background\Grass1.png" which is also correct. This is my mini test app : SuperStrict Framework bah.libxml validate("sample.xml") Function validate:Int(filename:String) Local reader:TxmlTextReader = TxmlTextReader.fromFile(filename) reader.setParserProp(XML_PARSER_VALIDATE, 1) Local ret:Int = reader.read() While ret = 1 ret = reader.read() Wend reader.free() If ret <> 0 Then RuntimeError "Error validating " + filename Return False End If Return True End Function All the files are in the same folder. |
| ||
How do you get it to output the errors? I just get the runetimeerror and then it closes. |
| ||
It should output to stderr as default, I believe. However, you can also handle errors yourself by overriding the default error function : SuperStrict Framework bah.libxml Import brl.standardio xmlSetErrorFunction(xmlError) validate("sample.xml") Function validate:Int(filename:String) Local reader:TxmlTextReader = TxmlTextReader.fromFile(filename) reader.setParserProp(XML_PARSER_VALIDATE, 1) Local ret:Int = reader.read() While ret = 1 ret = reader.read() Wend reader.free() If ret <> 0 Then RuntimeError "Error validating " + filename Return False End If Return True End Function Function xmlError(data:Object, error:TxmlError) Print "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" Print "Domain : " + error.getErrorDomain() Print "Message : " + error.getErrorMessage() Print "Code : " + error.getErrorCode() Print "Level : " + error.getErrorLevel() Print "Filename : " + error.getFilename() Print "Line : " + error.getLine() Print "Column : " + error.getColumn() End Function |