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
|