06 March 2009

Validate KML

I implement dynamic KML data using PHP + Postgis for a pet project. The problem is, Google Earth don't tell you the error when our kml file have problem, such as invalid KML. It just not appear in 'My Places' or 'Temporary Places'. So, I keep wondering whether I open correct link, or php not working, etc.

Previously how I debug is by check apache log or postgresql log. But just found the 'macho' way - by command line:

sudo apt-get install xmlstarlet
helmi@gandalf:/tmp> xmlstarlet val -e --xsd http://code.google.com/apis/kml/schema/kml21.xsd tree.kml
tree.kml - valid
# for offline xsd
helmi@gandalf:/tmp> wget -c http://code.google.com/apis/kml/schema/kml21.xsd
helmi@gandalf:/tmp> xmlstarlet val -e --xsd kml21.xsd tree.kml
tree.kml - valid
# without option -e, don't know status when xsd file not found
helmi@gandalf:/tmp> xmlstarlet val --xsd invalid_kml21.xsd tree.kml
# better version
helmi@gandalf:/tmp> xmlstarlet val -e --xsd invalid_kml21.xsd tree.kml
I/O warning : failed to load external entity "invalid_kml21.xsd"
Schemas parser error : Failed to locate the main schema resource at 'invalid_kml21.xsd'.
# of course you can validate kml generated by php
helmi@gandalf:/tmp> xmlstarlet val -e --xsd kml21.xsd http://localhost/~helmi/tree_kml/trees.php
http://localhost/~helmi/tree_kml/trees.php - valid

Google Earth gotchas:
* when click url http://localhost/~helmi/tree_kml/trees.php (this php return header with KML mimetype properly), and open with Google Earth, it not appear at 'Temporary Places'. One workaround, use apache url rewrite to redirect trees.kml to trees.php
not really gotcha, hint: header('Content-Disposition: attachment; filename="test_file.kml"');

RewriteEngine on
RewriteBase /~helmi/tree_kml/
RewriteRule trees\.kml$ trees.php [NC] # note that without option R

Now, use http://localhost/~helmi/tree_kml/trees.kml to display in GE properly