Updated Managing complex map files using XML entities (markdown)

ThomasG77 2011-12-27 11:05:29 -08:00
parent 83484906ec
commit 6b15f5911a

@ -20,9 +20,11 @@ components using external entities and XInclude.
## Mapnik XML support ## Mapnik XML support
Mapnik currently supports three different XML parsers: Mapnik currently supports three different XML parsers:
- the boost spirit based parser
- the tinyxml parser * the boost spirit based parser
- libxml2 * the tinyxml parser
* libxml2
The three parsers differ in size, external dependencies and the number of XML The three parsers differ in size, external dependencies and the number of XML
features they support. The most comprehensive parser is the libxml2 parser and features they support. The most comprehensive parser is the libxml2 parser and
it is the only one that supports XML entities. As of Mapnik 0.6.0 libxml2 is the default it is the only one that supports XML entities. As of Mapnik 0.6.0 libxml2 is the default
@ -34,9 +36,9 @@ when building the Mapnik source with SCons, and available in the Windows binarie
If not default in your Mapnik version (< 0.6.0) the libxml2 parser is enabled by setting the XMLPARSER option at If not default in your Mapnik version (< 0.6.0) the libxml2 parser is enabled by setting the XMLPARSER option at
compile time: compile time:
```sh
#!sh
$ python scons/scons.py configure XMLPARSER=libxml2 $ python scons/scons.py configure XMLPARSER=libxml2
```
Of course this requires the libxml2 library and, depending on the distribution Of course this requires the libxml2 library and, depending on the distribution
the corresponding devel package. If `xml2-config` is not in the PATH its location the corresponding devel package. If `xml2-config` is not in the PATH its location
@ -44,31 +46,31 @@ can be set using the `XML2_CONFIG` option.
For example, if you have installed the latest libxml2 on mac os x via Macports, you might need to do: For example, if you have installed the latest libxml2 on mac os x via Macports, you might need to do:
```sh
#!sh
$ python scons/scons.py configure XML2_CONFIG=/opt/local/bin/xml2-config $ python scons/scons.py configure XML2_CONFIG=/opt/local/bin/xml2-config
```
## Internal Entities ## Internal Entities
All XML parsers have some built-in entities to escape otherwise illegal All XML parsers have some built-in entities to escape otherwise illegal
characters: characters:
- &gt;
- &lt; * &gt;
- &amp; * &lt;
- &quot; * &amp;
- &apos; * &quot;
* &apos;
The XML document type definition (DTD) provides a way to declare new, user The XML document type definition (DTD) provides a way to declare new, user
defined entities: defined entities:
```xml
#!text/xml
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE Map[ <!DOCTYPE Map[
<!ENTITY water_color "#b5d0d0"> <!ENTITY water_color "#b5d0d0">
]> ]>
<Map bgcolor="&water_color;"/> <Map bgcolor="&water_color;"/>
```
This XML document declares an internal entity named water_color. This entity is This XML document declares an internal entity named water_color. This entity is
referenced by the bgcolor attribute of the Map element. The parser replaces all referenced by the bgcolor attribute of the Map element. The parser replaces all
@ -85,8 +87,7 @@ reoccurring value is a candidate for an entity.
It is allowed to nest entities: It is allowed to nest entities:
```xml
#!text/xml
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE Map[ <!DOCTYPE Map[
<!ENTITY home_dir "/home/david"> <!ENTITY home_dir "/home/david">
@ -100,17 +101,16 @@ It is allowed to nest entities:
</Rule> </Rule>
</Style> </Style>
</Map> </Map>
```
However, these internal entities are not suitable for larger blocks. They also However, these internal entities are not suitable for larger blocks. They also
do not help with sharing common styles and layers between different maps. do not help with sharing common styles and layers between different maps.
## External Entities ## External Entities
External entities are declared by adding the keyword SYSTEM: External entities are declared by adding the keyword SYSTEM:
```xml
#!text/xml
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE Map[ <!DOCTYPE Map[
<!ENTITY db_settings SYSTEM "settings/db_settings"> <!ENTITY db_settings SYSTEM "settings/db_settings">
@ -127,6 +127,7 @@ External entities are declared by adding the keyword SYSTEM:
</Datasource> </Datasource>
</Layer> </Layer>
</Map> </Map>
```
The entity declaration assigns the content of the file `settings/db_settings` to The entity declaration assigns the content of the file `settings/db_settings` to
the entity `&db_settings;`. When parsed the reference to `&db_settings;` in the the entity `&db_settings;`. When parsed the reference to `&db_settings;` in the
@ -135,12 +136,13 @@ filename is given the file is searched relative to the document. The file
`settings/db_settings` could look like this: `settings/db_settings` could look like this:
#!text/xml ```xml
<Parameter name="type">postgis</Parameter> <Parameter name="type">postgis</Parameter>
<Parameter name="host">www.example.org</Parameter> <Parameter name="host">www.example.org</Parameter>
<Parameter name="port">5433</Parameter> <Parameter name="port">5433</Parameter>
<Parameter name="user">david</Parameter> <Parameter name="user">david</Parameter>
<Parameter name="dbname">geo</Parameter> <Parameter name="dbname">geo</Parameter>
```
Note that this is not a legal XML document on its own because it does not have Note that this is not a legal XML document on its own because it does not have
a single root element. It is a list of elements. But the tags have to be well a single root element. It is a list of elements. But the tags have to be well
@ -152,7 +154,7 @@ limited form of parameterization. Consider the following example:
File earthquake.map: File earthquake.map:
#!text/xml ```xml
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE Map[ <!DOCTYPE Map[
<!ENTITY since_year "1970"> <!ENTITY since_year "1970">
@ -173,10 +175,11 @@ File earthquake.map:
&common_styles; &common_styles;
&common_layers; &common_layers;
</Map> </Map>
```
File earthquakes_since.lay: File earthquakes_since.lay:
#!text/xml ```xml
<Layer name="earthquakes_since" status="on"> <Layer name="earthquakes_since" status="on">
<StyleName>earthquakes</StyleName> <StyleName>earthquakes</StyleName>
<Datasource> <Datasource>
@ -190,6 +193,7 @@ File earthquakes_since.lay:
</Datasource> </Datasource>
</Layer> </Layer>
```
This is a quite flexible setup. It is very easy to add and remove thematic This is a quite flexible setup. It is very easy to add and remove thematic
overlays. Other overlays may use the same parameters by referencing the overlays. Other overlays may use the same parameters by referencing the
@ -198,7 +202,6 @@ same entities. Styles can be changed by replacing the reference to
many map files all referencing the same set of styles and layer files but with many map files all referencing the same set of styles and layer files but with
different settings. different settings.
## Entities Summary ## Entities Summary
Entities provide a way to use symbolic names in the map file. This improves Entities provide a way to use symbolic names in the map file. This improves
@ -208,7 +211,6 @@ general more maintainable. External entities can store whole blocks of XML.
This helps to build reusable collections of layers and styles. These reusable This helps to build reusable collections of layers and styles. These reusable
components can be parameterized using other entities as needed. components can be parameterized using other entities as needed.
## Including external files using XInclude ## Including external files using XInclude
libxml2 also provides support for decomposing large mapnik XML files through the use of XInclude. libxml2 also provides support for decomposing large mapnik XML files through the use of XInclude.
@ -217,7 +219,7 @@ To enable XInclude in your root file, modify the Map container tag, adding the x
File tests/data/good_maps/xinclude/map.xml: File tests/data/good_maps/xinclude/map.xml:
#!text/xml ```xml
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE Map > <!DOCTYPE Map >
<Map xmlns:xi="http://www.w3.org/2001/XInclude" srs="+init=epsg:4326" bgcolor="rgb(255,255,255)" > <Map xmlns:xi="http://www.w3.org/2001/XInclude" srs="+init=epsg:4326" bgcolor="rgb(255,255,255)" >
@ -229,6 +231,7 @@ File tests/data/good_maps/xinclude/map.xml:
<xi:include href="layers.xml" /> <xi:include href="layers.xml" />
</Map> </Map>
```
Included files wrap their content within an Include tag. XInclude replaces the xi:include tags with the contents of the included file, yielding a single, merged XML document. Included files wrap their content within an Include tag. XInclude replaces the xi:include tags with the contents of the included file, yielding a single, merged XML document.
mapnik's XML parser then merges the contents of the Include tag into the Map tag, resulting in an XML document tree identical to one produced by processing a single file containing mapnik's XML parser then merges the contents of the Include tag into the Map tag, resulting in an XML document tree identical to one produced by processing a single file containing
@ -236,7 +239,7 @@ all Style and Layer tags.
File styles.xml: File styles.xml:
#!text/xml ```xml
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Include xmlns:xi="http://www.w3.org/2001/XInclude"> <Include xmlns:xi="http://www.w3.org/2001/XInclude">
@ -254,10 +257,11 @@ File styles.xml:
</Style> </Style>
</Include> </Include>
```
File layers.xml: File layers.xml:
#!text/xml ```xml
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Include xmlns:xi="http://www.w3.org/2001/XInclude"> <Include xmlns:xi="http://www.w3.org/2001/XInclude">
@ -270,6 +274,7 @@ File layers.xml:
</Layer> </Layer>
</Include> </Include>
```
## Combining XInclude and External Entities ## Combining XInclude and External Entities
@ -279,7 +284,7 @@ A common pattern found in mapnik XML file sets is specifying the zoom levels for
file: zoomsymbols.txt file: zoomsymbols.txt
#!text/html ```xml
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!ENTITY zoom00max "750000000" > <!ENTITY zoom00max "750000000" >
@ -290,14 +295,14 @@ file: zoomsymbols.txt
<!ENTITY zoom02max "250000000" > <!ENTITY zoom02max "250000000" >
<!ENTITY zoom02min "130000000" > <!ENTITY zoom02min "130000000" >
```
Adding a DOCTYPE line to the layers.xml file to include the external entities file, and adding parameterized minzoom and maxzoom attributes to the layer yields the file below: Adding a DOCTYPE line to the layers.xml file to include the external entities file, and adding parameterized minzoom and maxzoom attributes to the layer yields the file below:
File layers_with_entities.xml: File layers_with_entities.xml:
#!text/xml ```xml
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE Include SYSTEM "zoomsymbols.txt"> <!DOCTYPE Include SYSTEM "zoomsymbols.txt">
@ -312,6 +317,7 @@ File layers_with_entities.xml:
</Layer> </Layer>
</Include> </Include>
```
## Further Reading ## Further Reading