[SCM] PostGIS branch master updated. 3.4.0rc1-910-gc8ec52a5b
git at osgeo.org
git at osgeo.org
Wed Jan 31 12:50:30 PST 2024
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "PostGIS".
The branch, master has been updated
via c8ec52a5b4ba47d9b58fb9e06565425dd7461350 (commit)
from 77c04eddfffef86d6ae4c3b78bdb9471c021c562 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit c8ec52a5b4ba47d9b58fb9e06565425dd7461350
Author: Paul Ramsey <pramsey at cleverelephant.ca>
Date: Wed Jan 31 12:44:35 2024 -0800
Change XML parsing to use default (SAX2) parser
diff --git a/postgis/lwgeom_in_gml.c b/postgis/lwgeom_in_gml.c
index 6fe568eb6..6bdb81998 100644
--- a/postgis/lwgeom_in_gml.c
+++ b/postgis/lwgeom_in_gml.c
@@ -123,6 +123,28 @@ Datum geom_from_gml(PG_FUNCTION_ARGS)
}
+static inline bool
+is_gml_element(xmlNodePtr xn, const char *gml_name)
+{
+ char *colon_pos;
+ char *node_name;
+
+ /* Not an element node, can't do anything */
+ if (!xn || xn->type != XML_ELEMENT_NODE)
+ return false;
+
+ /* If there's a colon in the element name, */
+ /* move past it before checking for equality with */
+ /* the element name we are looking for */
+ node_name = (char*)xn->name;
+ colon_pos = strchr(node_name, ':');
+ if (colon_pos)
+ node_name = colon_pos + 1;
+
+ return strcmp(node_name, gml_name) == 0;
+}
+
+
/**
* Return false if current element namespace is not a GML one
* Return true otherwise.
@@ -172,9 +194,10 @@ static bool is_gml_namespace(xmlNodePtr xnode, bool is_strict)
* Retrieve a GML property from a node or NULL otherwise
* Respect namespaces if presents in the node element
*/
-static xmlChar *gmlGetProp(xmlNodePtr xnode, xmlChar *prop)
+static xmlChar *gmlGetProp(xmlNodePtr xnode, const char *charProp)
{
xmlChar *value;
+ xmlChar *prop = (xmlChar*)charProp;
if (!is_gml_namespace(xnode, true))
return xmlGetProp(xnode, prop);
@@ -277,7 +300,7 @@ static xmlNodePtr get_xlink_node(xmlNodePtr xnode)
for (node = xnode ; node != NULL ; node = node->parent)
{
if (node->type != XML_ELEMENT_NODE) continue;
- node_id = gmlGetProp(node, (xmlChar *) "id");
+ node_id = gmlGetProp(node, "id");
if (node_id != NULL)
{
if (!xmlStrcmp(node_id, p))
@@ -421,7 +444,7 @@ static void parse_gml_srs(xmlNodePtr xnode, gmlSrs *srs)
char sep = ':';
node = xnode;
- srsname = gmlGetProp(node, (xmlChar *) "srsName");
+ srsname = gmlGetProp(node, "srsName");
/*printf("srsname %s\n",srsname);*/
if (!srsname)
{
@@ -592,7 +615,7 @@ static POINTARRAY* parse_gml_coordinates(xmlNodePtr xnode, bool *hasz)
*/
/* Retrieve separator between coordinates tuples */
- gml_ts = gmlGetProp(xnode, (xmlChar *) "ts");
+ gml_ts = gmlGetProp(xnode, "ts");
if (gml_ts == NULL) ts = ' ';
else
{
@@ -603,7 +626,7 @@ static POINTARRAY* parse_gml_coordinates(xmlNodePtr xnode, bool *hasz)
}
/* Retrieve separator between each coordinate */
- gml_cs = gmlGetProp(xnode, (xmlChar *) "cs");
+ gml_cs = gmlGetProp(xnode, "cs");
if (gml_cs == NULL) cs = ',';
else
{
@@ -614,7 +637,7 @@ static POINTARRAY* parse_gml_coordinates(xmlNodePtr xnode, bool *hasz)
}
/* Retrieve decimal separator */
- gml_dec = gmlGetProp(xnode, (xmlChar *) "decimal");
+ gml_dec = gmlGetProp(xnode, "decimal");
if (gml_dec == NULL) dec = '.';
else
{
@@ -704,7 +727,7 @@ static POINTARRAY* parse_gml_coord(xmlNodePtr xnode, bool *hasz)
if (xyz->type != XML_ELEMENT_NODE) continue;
if (!is_gml_namespace(xyz, false)) continue;
- if (!strcmp((char *) xyz->name, "X"))
+ if (is_gml_element(xyz, "X"))
{
if (x) gml_lwpgerror("invalid GML representation", 21);
c = xmlNodeGetContent(xyz);
@@ -712,7 +735,7 @@ static POINTARRAY* parse_gml_coord(xmlNodePtr xnode, bool *hasz)
x = true;
xmlFree(c);
}
- else if (!strcmp((char *) xyz->name, "Y"))
+ else if (is_gml_element(xyz, "Y"))
{
if (y) gml_lwpgerror("invalid GML representation", 22);
c = xmlNodeGetContent(xyz);
@@ -720,7 +743,7 @@ static POINTARRAY* parse_gml_coord(xmlNodePtr xnode, bool *hasz)
y = true;
xmlFree(c);
}
- else if (!strcmp((char *) xyz->name, "Z"))
+ else if (is_gml_element(xyz, "Z"))
{
if (z) gml_lwpgerror("invalid GML representation", 23);
c = xmlNodeGetContent(xyz);
@@ -754,9 +777,9 @@ static POINTARRAY* parse_gml_pos(xmlNodePtr xnode, bool *hasz)
/* HasZ, !HasM, 1 Point */
dpa = ptarray_construct_empty(1, 0, 1);
- dimension = gmlGetProp(xnode, (xmlChar *) "srsDimension");
+ dimension = gmlGetProp(xnode, "srsDimension");
if (dimension == NULL) /* in GML 3.0.0 it was dimension */
- dimension = gmlGetProp(xnode, (xmlChar *) "dimension");
+ dimension = gmlGetProp(xnode, "dimension");
if (dimension == NULL) dim = 2; /* We assume that we are in 2D */
else
{
@@ -819,9 +842,9 @@ static POINTARRAY* parse_gml_poslist(xmlNodePtr xnode, bool *hasz)
bool digit;
/* Retrieve gml:srsDimension attribute if any */
- dimension = gmlGetProp(xnode, (xmlChar *) "srsDimension");
+ dimension = gmlGetProp(xnode, "srsDimension");
if (dimension == NULL) /* in GML 3.0.0 it was dimension */
- dimension = gmlGetProp(xnode, (xmlChar *) "dimension");
+ dimension = gmlGetProp(xnode, "dimension");
if (dimension == NULL) dim = 2; /* We assume that we are in common 2D */
else
{
@@ -902,44 +925,43 @@ static POINTARRAY* parse_gml_data(xmlNodePtr xnode, bool *hasz, int *root_srid)
if (!is_gml_namespace(xa, false)) continue;
if (xa->name == NULL) continue;
- if (!strcmp((char *) xa->name, "pos"))
+ if (is_gml_element(xa, "pos"))
{
tmp_pa = parse_gml_pos(xa, hasz);
if (pa == NULL) pa = tmp_pa;
else pa = ptarray_merge(pa, tmp_pa);
}
- else if (!strcmp((char *) xa->name, "posList"))
+ else if (is_gml_element(xa, "posList"))
{
tmp_pa = parse_gml_poslist(xa, hasz);
if (pa == NULL) pa = tmp_pa;
else pa = ptarray_merge(pa, tmp_pa);
}
- else if (!strcmp((char *) xa->name, "coordinates"))
+ else if (is_gml_element(xa, "coordinates"))
{
tmp_pa = parse_gml_coordinates(xa, hasz);
if (pa == NULL) pa = tmp_pa;
else pa = ptarray_merge(pa, tmp_pa);
}
- else if (!strcmp((char *) xa->name, "coord"))
+ else if (is_gml_element(xa, "coord"))
{
tmp_pa = parse_gml_coord(xa, hasz);
if (pa == NULL) pa = tmp_pa;
else pa = ptarray_merge(pa, tmp_pa);
}
- else if (!strcmp((char *) xa->name, "pointRep") ||
- !strcmp((char *) xa->name, "pointProperty"))
+ else if (is_gml_element(xa, "pointRep") ||
+ is_gml_element(xa, "pointProperty"))
{
-
found = false;
for (xb = xa->children ; xb != NULL ; xb = xb->next)
{
if (xb->type != XML_ELEMENT_NODE) continue;
if (!is_gml_namespace(xb, false)) continue;
- if (!strcmp((char *) xb->name, "Point"))
+ if (is_gml_element(xb, "Point"))
{
found = true;
break;
@@ -1064,7 +1086,7 @@ static LWGEOM* parse_gml_curve(xmlNodePtr xnode, bool *hasz, int *root_srid)
{
if (xa->type != XML_ELEMENT_NODE) continue;
if (!is_gml_namespace(xa, false)) continue;
- if (!strcmp((char *) xa->name, "segments"))
+ if (is_gml_element(xa, "segments"))
{
found = true;
break;
@@ -1079,10 +1101,11 @@ static LWGEOM* parse_gml_curve(xmlNodePtr xnode, bool *hasz, int *root_srid)
{
if (xa->type != XML_ELEMENT_NODE) continue;
if (!is_gml_namespace(xa, false)) continue;
- if (strcmp((char *) xa->name, "LineStringSegment")) continue;
+
+ if (!is_gml_element(xa, "LineStringSegment")) continue;
/* GML SF is restricted to linear interpolation */
- interpolation = gmlGetProp(xa, (xmlChar *) "interpolation");
+ interpolation = gmlGetProp(xa, "interpolation");
if (interpolation != NULL)
{
if (strcmp((char *) interpolation, "linear"))
@@ -1209,14 +1232,15 @@ static LWGEOM* parse_gml_polygon(xmlNodePtr xnode, bool *hasz, int *root_srid)
/* Polygon/exterior -> GML 3.1.1 */
if (xa->type != XML_ELEMENT_NODE) continue;
if (!is_gml_namespace(xa, false)) continue;
- if (strcmp((char *) xa->name, "outerBoundaryIs") &&
- strcmp((char *) xa->name, "exterior")) continue;
+ if (!(is_gml_element(xa, "outerBoundaryIs") ||
+ is_gml_element(xa, "exterior")))
+ continue;
for (xb = xa->children ; xb != NULL ; xb = xb->next)
{
if (xb->type != XML_ELEMENT_NODE) continue;
if (!is_gml_namespace(xb, false)) continue;
- if (strcmp((char *) xb->name, "LinearRing")) continue;
+ if (!is_gml_element(xb, "LinearRing")) continue;
ppa = (POINTARRAY**) lwalloc(sizeof(POINTARRAY*));
ppa[0] = parse_gml_data(xb->children, hasz, root_srid);
@@ -1240,14 +1264,15 @@ static LWGEOM* parse_gml_polygon(xmlNodePtr xnode, bool *hasz, int *root_srid)
/* Polygon/interior -> GML 3.1.1 */
if (xa->type != XML_ELEMENT_NODE) continue;
if (!is_gml_namespace(xa, false)) continue;
- if (strcmp((char *) xa->name, "innerBoundaryIs") &&
- strcmp((char *) xa->name, "interior")) continue;
+ if (!(is_gml_element(xa, "innerBoundaryIs") ||
+ is_gml_element(xa, "interior")))
+ continue;
for (xb = xa->children ; xb != NULL ; xb = xb->next)
{
if (xb->type != XML_ELEMENT_NODE) continue;
if (!is_gml_namespace(xb, false)) continue;
- if (strcmp((char *) xb->name, "LinearRing")) continue;
+ if (!is_gml_element(xb, "LinearRing")) continue;
ppa = (POINTARRAY**) lwrealloc((POINTARRAY *) ppa,
sizeof(POINTARRAY*) * (ring + 1));
@@ -1296,7 +1321,7 @@ static LWGEOM* parse_gml_triangle(xmlNodePtr xnode, bool *hasz, int *root_srid)
/* GML SF is restricted to planar interpolation
NOTA: I know Triangle is not part of SF, but
we have to be consistent with other surfaces */
- interpolation = gmlGetProp(xnode, (xmlChar *) "interpolation");
+ interpolation = gmlGetProp(xnode, "interpolation");
if (interpolation != NULL)
{
if (strcmp((char *) interpolation, "planar"))
@@ -1311,14 +1336,14 @@ static LWGEOM* parse_gml_triangle(xmlNodePtr xnode, bool *hasz, int *root_srid)
/* Triangle/exterior */
if (xa->type != XML_ELEMENT_NODE) continue;
if (!is_gml_namespace(xa, false)) continue;
- if (strcmp((char *) xa->name, "exterior")) continue;
+ if (!is_gml_element(xa, "exterior")) continue;
for (xb = xa->children ; xb != NULL ; xb = xb->next)
{
/* Triangle/exterior/LinearRing */
if (xb->type != XML_ELEMENT_NODE) continue;
if (!is_gml_namespace(xb, false)) continue;
- if (strcmp((char *) xb->name, "LinearRing")) continue;
+ if (!is_gml_element(xb, "LinearRing")) continue;
pa = (POINTARRAY*) lwalloc(sizeof(POINTARRAY));
pa = parse_gml_data(xb->children, hasz, root_srid);
@@ -1357,11 +1382,11 @@ static LWGEOM* parse_gml_patch(xmlNodePtr xnode, bool *hasz, int *root_srid)
gmlSrs srs;
/* PolygonPatch */
- if (strcmp((char *) xnode->name, "PolygonPatch"))
+ if (!is_gml_element(xnode, "PolygonPatch"))
gml_lwpgerror("invalid GML representation", 48);
/* GML SF is restricted to planar interpolation */
- interpolation = gmlGetProp(xnode, (xmlChar *) "interpolation");
+ interpolation = gmlGetProp(xnode, "interpolation");
if (interpolation != NULL)
{
if (strcmp((char *) interpolation, "planar"))
@@ -1375,14 +1400,14 @@ static LWGEOM* parse_gml_patch(xmlNodePtr xnode, bool *hasz, int *root_srid)
for (xa = xnode->children ; xa != NULL ; xa = xa->next)
{
if (!is_gml_namespace(xa, false)) continue;
- if (strcmp((char *) xa->name, "exterior")) continue;
+ if (!is_gml_element(xa, "exterior")) continue;
/* PolygonPatch/exterior/LinearRing */
for (xb = xa->children ; xb != NULL ; xb = xb->next)
{
if (xb->type != XML_ELEMENT_NODE) continue;
if (!is_gml_namespace(xb, false)) continue;
- if (strcmp((char *) xb->name, "LinearRing")) continue;
+ if (!is_gml_element(xb, "LinearRing")) continue;
ppa = (POINTARRAY**) lwalloc(sizeof(POINTARRAY*));
ppa[0] = parse_gml_data(xb->children, hasz, root_srid);
@@ -1406,13 +1431,13 @@ static LWGEOM* parse_gml_patch(xmlNodePtr xnode, bool *hasz, int *root_srid)
{
if (xa->type != XML_ELEMENT_NODE) continue;
if (!is_gml_namespace(xa, false)) continue;
- if (strcmp((char *) xa->name, "interior")) continue;
+ if (!is_gml_element(xa, "interior")) continue;
/* PolygonPatch/interior/LinearRing */
for (xb = xa->children ; xb != NULL ; xb = xb->next)
{
if (xb->type != XML_ELEMENT_NODE) continue;
- if (strcmp((char *) xb->name, "LinearRing")) continue;
+ if (!is_gml_element(xb, "LinearRing")) continue;
ppa = (POINTARRAY**) lwrealloc((POINTARRAY *) ppa,
sizeof(POINTARRAY*) * (ring + 1));
@@ -1461,7 +1486,7 @@ static LWGEOM* parse_gml_surface(xmlNodePtr xnode, bool *hasz, int *root_srid)
{
if (xa->type != XML_ELEMENT_NODE) continue;
if (!is_gml_namespace(xa, false)) continue;
- if (!strcmp((char *) xa->name, "patches"))
+ if (is_gml_element(xa, "patches"))
{
found = true;
break;
@@ -1474,7 +1499,7 @@ static LWGEOM* parse_gml_surface(xmlNodePtr xnode, bool *hasz, int *root_srid)
{
if (xa->type != XML_ELEMENT_NODE) continue;
if (!is_gml_namespace(xa, false)) continue;
- if (strcmp((char *) xa->name, "PolygonPatch")) continue;
+ if (!is_gml_element(xa, "PolygonPatch")) continue;
patch++;
/* SQL/MM define ST_CurvePolygon as a single patch only,
@@ -1522,8 +1547,8 @@ static LWGEOM* parse_gml_tin(xmlNodePtr xnode, bool *hasz, int *root_srid)
{
if (xa->type != XML_ELEMENT_NODE) continue;
if (!is_gml_namespace(xa, false)) continue;
- if (!strcmp((char *) xa->name, "patches") ||
- !strcmp((char *) xa->name, "trianglePatches"))
+ if (is_gml_element(xa, "patches") ||
+ is_gml_element(xa, "trianglePatches"))
{
found = true;
break;
@@ -1536,7 +1561,7 @@ static LWGEOM* parse_gml_tin(xmlNodePtr xnode, bool *hasz, int *root_srid)
{
if (xa->type != XML_ELEMENT_NODE) continue;
if (!is_gml_namespace(xa, false)) continue;
- if (strcmp((char *) xa->name, "Triangle")) continue;
+ if (!is_gml_element(xa, "Triangle")) continue;
if (xa->children != NULL)
geom = (LWGEOM*) lwtin_add_lwtriangle((LWTIN *) geom,
@@ -1572,7 +1597,7 @@ static LWGEOM* parse_gml_mpoint(xmlNodePtr xnode, bool *hasz, int *root_srid)
/* MultiPoint/pointMember */
if (xa->type != XML_ELEMENT_NODE) continue;
if (!is_gml_namespace(xa, false)) continue;
- if (!strcmp((char *) xa->name, "pointMembers"))
+ if (is_gml_element(xa, "pointMembers"))
{
for (xb = xa->children ; xb != NULL ; xb = xb->next)
{
@@ -1581,7 +1606,7 @@ static LWGEOM* parse_gml_mpoint(xmlNodePtr xnode, bool *hasz, int *root_srid)
(LWPOINT*)parse_gml(xb, hasz, root_srid));
}
}
- else if (!strcmp((char *) xa->name, "pointMember"))
+ else if (is_gml_element(xa, "pointMember"))
{
if (xa->children != NULL)
geom = (LWGEOM*)lwmpoint_add_lwpoint((LWMPOINT*)geom,
@@ -1618,7 +1643,7 @@ static LWGEOM* parse_gml_mline(xmlNodePtr xnode, bool *hasz, int *root_srid)
/* MultiLineString/lineStringMember */
if (xa->type != XML_ELEMENT_NODE) continue;
if (!is_gml_namespace(xa, false)) continue;
- if (strcmp((char *) xa->name, "lineStringMember")) continue;
+ if (!is_gml_element(xa, "lineStringMember")) continue;
if (xa->children != NULL)
geom = (LWGEOM*)lwmline_add_lwline((LWMLINE*)geom,
(LWLINE*)parse_gml(xa->children, hasz, root_srid));
@@ -1654,7 +1679,7 @@ static LWGEOM* parse_gml_mcurve(xmlNodePtr xnode, bool *hasz, int *root_srid)
/* MultiCurve/curveMember */
if (xa->type != XML_ELEMENT_NODE) continue;
if (!is_gml_namespace(xa, false)) continue;
- if (!strcmp((char *) xa->name, "curveMembers"))
+ if (is_gml_element(xa, "curveMembers"))
{
for (xb = xa->children ; xb != NULL ; xb = xb->next)
{
@@ -1663,7 +1688,7 @@ static LWGEOM* parse_gml_mcurve(xmlNodePtr xnode, bool *hasz, int *root_srid)
(LWLINE*)parse_gml(xb, hasz, root_srid));
}
}
- else if (!strcmp((char *) xa->name, "curveMember"))
+ else if (is_gml_element(xa, "curveMember"))
{
if (xa->children != NULL)
geom = (LWGEOM*)lwmline_add_lwline((LWMLINE*)geom,
@@ -1700,7 +1725,7 @@ static LWGEOM* parse_gml_mpoly(xmlNodePtr xnode, bool *hasz, int *root_srid)
/* MultiPolygon/polygonMember */
if (xa->type != XML_ELEMENT_NODE) continue;
if (!is_gml_namespace(xa, false)) continue;
- if (strcmp((char *) xa->name, "polygonMember")) continue;
+ if (!is_gml_element(xa, "polygonMember")) continue;
if (xa->children != NULL)
geom = (LWGEOM*)lwmpoly_add_lwpoly((LWMPOLY*)geom,
(LWPOLY*)parse_gml(xa->children, hasz, root_srid));
@@ -1735,7 +1760,7 @@ static LWGEOM* parse_gml_msurface(xmlNodePtr xnode, bool *hasz, int *root_srid)
/* MultiSurface/surfaceMember */
if (xa->type != XML_ELEMENT_NODE) continue;
if (!is_gml_namespace(xa, false)) continue;
- if (!strcmp((char *) xa->name, "surfaceMembers"))
+ if (is_gml_element(xa, "surfaceMembers"))
{
for (xb = xa->children ; xb != NULL ; xb = xb->next)
{
@@ -1744,7 +1769,7 @@ static LWGEOM* parse_gml_msurface(xmlNodePtr xnode, bool *hasz, int *root_srid)
(LWPOLY*)parse_gml(xb, hasz, root_srid));
}
}
- else if (!strcmp((char *) xa->name, "surfaceMember"))
+ else if (is_gml_element(xa, "surfaceMember"))
{
if (xa->children != NULL)
geom = (LWGEOM*)lwmpoly_add_lwpoly((LWMPOLY*)geom,
@@ -1783,7 +1808,7 @@ static LWGEOM* parse_gml_psurface(xmlNodePtr xnode, bool *hasz, int *root_srid)
{
if (xa->type != XML_ELEMENT_NODE) continue;
if (!is_gml_namespace(xa, false)) continue;
- if (!strcmp((char *) xa->name, "polygonPatches"))
+ if (is_gml_element(xa, "polygonPatches"))
{
found = true;
break;
@@ -1796,7 +1821,7 @@ static LWGEOM* parse_gml_psurface(xmlNodePtr xnode, bool *hasz, int *root_srid)
/* PolyhedralSurface/polygonPatches/PolygonPatch */
if (xa->type != XML_ELEMENT_NODE) continue;
if (!is_gml_namespace(xa, false)) continue;
- if (strcmp((char *) xa->name, "PolygonPatch")) continue;
+ if (!is_gml_element(xa, "PolygonPatch")) continue;
geom = (LWGEOM*)lwpsurface_add_lwpoly((LWPSURFACE*)geom,
(LWPOLY*)parse_gml_patch(xa, hasz, root_srid));
@@ -1836,10 +1861,10 @@ static LWGEOM* parse_gml_coll(xmlNodePtr xnode, bool *hasz, int *root_srid)
* polygonMember are parts of geometryMember
* substitution group
*/
- if ( !strcmp((char *) xa->name, "pointMember")
- || !strcmp((char *) xa->name, "lineStringMember")
- || !strcmp((char *) xa->name, "polygonMember")
- || !strcmp((char *) xa->name, "geometryMember"))
+ if ( is_gml_element(xa, "pointMember")
+ || is_gml_element(xa, "lineStringMember")
+ || is_gml_element(xa, "polygonMember")
+ || is_gml_element(xa, "geometryMember"))
{
if (xa->children == NULL) break;
geom = (LWGEOM*)lwcollection_add_lwgeom((LWCOLLECTION *)geom,
@@ -1865,7 +1890,7 @@ lwgeom_from_gml(const char *xml, int xml_size)
/* Begin to Parse XML doc */
xmlInitParser();
- xmldoc = xmlReadMemory(xml, xml_size, NULL, NULL, XML_PARSE_SAX1);
+ xmldoc = xmlReadMemory(xml, xml_size, NULL, NULL, 0);
if (!xmldoc)
{
xmlCleanupParser();
@@ -1917,8 +1942,12 @@ static LWGEOM* parse_gml(xmlNodePtr xnode, bool *hasz, int *root_srid)
xmlNodePtr xa = xnode;
gmlSrs srs;
- while (xa != NULL && (xa->type != XML_ELEMENT_NODE
- || !is_gml_namespace(xa, false))) xa = xa->next;
+ /* Scroll forward to the root node */
+ while (xa != NULL &&
+ (xa->type != XML_ELEMENT_NODE || !is_gml_namespace(xa, false)))
+ {
+ xa = xa->next;
+ }
if (xa == NULL) gml_lwpgerror("invalid GML representation", 55);
@@ -1928,50 +1957,50 @@ static LWGEOM* parse_gml(xmlNodePtr xnode, bool *hasz, int *root_srid)
*root_srid = srs.srid;
}
- if (!strcmp((char *) xa->name, "Point"))
+ if (is_gml_element(xa, "Point"))
return parse_gml_point(xa, hasz, root_srid);
- if (!strcmp((char *) xa->name, "LineString"))
+ if (is_gml_element(xa, "LineString"))
return parse_gml_line(xa, hasz, root_srid);
- if (!strcmp((char *) xa->name, "Curve"))
+ if (is_gml_element(xa, "Curve"))
return parse_gml_curve(xa, hasz, root_srid);
- if (!strcmp((char *) xa->name, "LinearRing"))
+ if (is_gml_element(xa, "LinearRing"))
return parse_gml_linearring(xa, hasz, root_srid);
- if (!strcmp((char *) xa->name, "Polygon"))
+ if (is_gml_element(xa, "Polygon"))
return parse_gml_polygon(xa, hasz, root_srid);
- if (!strcmp((char *) xa->name, "Triangle"))
+ if (is_gml_element(xa, "Triangle"))
return parse_gml_triangle(xa, hasz, root_srid);
- if (!strcmp((char *) xa->name, "Surface"))
+ if (is_gml_element(xa, "Surface"))
return parse_gml_surface(xa, hasz, root_srid);
- if (!strcmp((char *) xa->name, "MultiPoint"))
+ if (is_gml_element(xa, "MultiPoint"))
return parse_gml_mpoint(xa, hasz, root_srid);
- if (!strcmp((char *) xa->name, "MultiLineString"))
+ if (is_gml_element(xa, "MultiLineString"))
return parse_gml_mline(xa, hasz, root_srid);
- if (!strcmp((char *) xa->name, "MultiCurve"))
+ if (is_gml_element(xa, "MultiCurve"))
return parse_gml_mcurve(xa, hasz, root_srid);
- if (!strcmp((char *) xa->name, "MultiPolygon"))
+ if (is_gml_element(xa, "MultiPolygon"))
return parse_gml_mpoly(xa, hasz, root_srid);
- if (!strcmp((char *) xa->name, "MultiSurface"))
+ if (is_gml_element(xa, "MultiSurface"))
return parse_gml_msurface(xa, hasz, root_srid);
- if (!strcmp((char *) xa->name, "PolyhedralSurface"))
+ if (is_gml_element(xa, "PolyhedralSurface"))
return parse_gml_psurface(xa, hasz, root_srid);
- if ((!strcmp((char *) xa->name, "Tin")) ||
- !strcmp((char *) xa->name, "TriangulatedSurface" ))
+ if (is_gml_element(xa, "Tin") ||
+ is_gml_element(xa, "TriangulatedSurface"))
return parse_gml_tin(xa, hasz, root_srid);
- if (!strcmp((char *) xa->name, "MultiGeometry"))
+ if (is_gml_element(xa, "MultiGeometry"))
return parse_gml_coll(xa, hasz, root_srid);
gml_lwpgerror("invalid GML representation", 56);
diff --git a/postgis/lwgeom_in_kml.c b/postgis/lwgeom_in_kml.c
index 75ba53833..0185587a3 100644
--- a/postgis/lwgeom_in_kml.c
+++ b/postgis/lwgeom_in_kml.c
@@ -64,6 +64,28 @@ static LWGEOM* parse_kml(xmlNodePtr xnode, bool *hasz);
#define KML_NS ((char *) "http://www.opengis.net/kml/2.2")
+static inline bool
+is_kml_element(xmlNodePtr xn, const char *kml_name)
+{
+ char *colon_pos;
+ char *node_name;
+
+ /* Not an element node, can't do anything */
+ if (!xn || xn->type != XML_ELEMENT_NODE)
+ return false;
+
+ /* If there's a colon in the element name, */
+ /* move past it before checking for equality with */
+ /* the element name we are looking for */
+ node_name = (char*)xn->name;
+ colon_pos = strchr(node_name, ':');
+ if (colon_pos)
+ node_name = colon_pos + 1;
+
+ return strcmp(node_name, kml_name) == 0;
+}
+
+
/**
* Ability to parse KML geometry fragment and to return an LWGEOM
* or an error message.
@@ -88,7 +110,8 @@ Datum geom_from_kml(PG_FUNCTION_ARGS)
/* Begin to Parse XML doc */
xmlInitParser();
- xmldoc = xmlReadMemory(xml, xml_size, NULL, NULL, XML_PARSE_SAX1);
+ xmldoc = xmlReadMemory(xml, xml_size, NULL, NULL, 0);
+ // xmldoc = xmlReadMemory(xml, xml_size, NULL, NULL, XML_PARSE_SAX1);
if (!xmldoc || (xmlroot = xmlDocGetRootElement(xmldoc)) == NULL)
{
xmlFreeDoc(xmldoc);
@@ -288,7 +311,7 @@ static POINTARRAY* parse_kml_coordinates(xmlNodePtr xnode, bool *hasz)
{
if (xnode->type != XML_ELEMENT_NODE) continue;
if (!is_kml_namespace(xnode, false)) continue;
- if (strcmp((char *) xnode->name, "coordinates")) continue;
+ if (!is_kml_element(xnode, "coordinates")) continue;
found = true;
break;
@@ -404,14 +427,14 @@ static LWGEOM* parse_kml_polygon(xmlNodePtr xnode, bool *hasz)
/* Polygon/outerBoundaryIs */
if (xa->type != XML_ELEMENT_NODE) continue;
if (!is_kml_namespace(xa, false)) continue;
- if (strcmp((char *) xa->name, "outerBoundaryIs")) continue;
+ if (!is_kml_element(xa, "outerBoundaryIs")) continue;
for (xb = xa->children ; xb != NULL ; xb = xb->next)
{
if (xb->type != XML_ELEMENT_NODE) continue;
if (!is_kml_namespace(xb, false)) continue;
- if (strcmp((char *) xb->name, "LinearRing")) continue;
+ if (!is_kml_element(xb, "LinearRing")) continue;
ppa = (POINTARRAY**) lwalloc(sizeof(POINTARRAY*));
ppa[0] = parse_kml_coordinates(xb->children, hasz);
@@ -440,14 +463,14 @@ static LWGEOM* parse_kml_polygon(xmlNodePtr xnode, bool *hasz)
/* Polygon/innerBoundaryIs */
if (xa->type != XML_ELEMENT_NODE) continue;
if (!is_kml_namespace(xa, false)) continue;
- if (strcmp((char *) xa->name, "innerBoundaryIs")) continue;
+ if (!is_kml_element(xa, "innerBoundaryIs")) continue;
for (xb = xa->children ; xb != NULL ; xb = xb->next)
{
if (xb->type != XML_ELEMENT_NODE) continue;
if (!is_kml_namespace(xb, false)) continue;
- if (strcmp((char *) xb->name, "LinearRing")) continue;
+ if (!is_kml_element(xb, "LinearRing")) continue;
ppa = (POINTARRAY**) lwrealloc(ppa, sizeof(POINTARRAY*) * (ring + 1));
ppa[ring] = parse_kml_coordinates(xb->children, hasz);
@@ -491,10 +514,10 @@ static LWGEOM* parse_kml_multi(xmlNodePtr xnode, bool *hasz)
if (xa->type != XML_ELEMENT_NODE) continue;
if (!is_kml_namespace(xa, false)) continue;
- if ( !strcmp((char *) xa->name, "Point")
- || !strcmp((char *) xa->name, "LineString")
- || !strcmp((char *) xa->name, "Polygon")
- || !strcmp((char *) xa->name, "MultiGeometry"))
+ if ( is_kml_element(xa, "Point")
+ || is_kml_element(xa, "LineString")
+ || is_kml_element(xa, "Polygon")
+ || is_kml_element(xa, "MultiGeometry"))
{
if (xa->children == NULL) break;
@@ -518,16 +541,16 @@ static LWGEOM* parse_kml(xmlNodePtr xnode, bool *hasz)
if (xa == NULL) lwpgerror("invalid KML representation");
- if (!strcmp((char *) xa->name, "Point"))
+ if (is_kml_element(xa, "Point"))
return parse_kml_point(xa, hasz);
- if (!strcmp((char *) xa->name, "LineString"))
+ if (is_kml_element(xa, "LineString"))
return parse_kml_line(xa, hasz);
- if (!strcmp((char *) xa->name, "Polygon"))
+ if (is_kml_element(xa, "Polygon"))
return parse_kml_polygon(xa, hasz);
- if (!strcmp((char *) xa->name, "MultiGeometry"))
+ if (is_kml_element(xa, "MultiGeometry"))
return parse_kml_multi(xa, hasz);
lwpgerror("invalid KML representation");
diff --git a/postgis/lwgeom_in_marc21.c b/postgis/lwgeom_in_marc21.c
index 69ba2f975..282db4d56 100644
--- a/postgis/lwgeom_in_marc21.c
+++ b/postgis/lwgeom_in_marc21.c
@@ -64,7 +64,7 @@ Datum ST_GeomFromMARC21(PG_FUNCTION_ARGS) {
xml_size = VARSIZE_ANY_EXHDR(xml_input);
xmlInitParser();
- xmldoc = xmlReadMemory(xml, xml_size, NULL, NULL, XML_PARSE_SAX1);
+ xmldoc = xmlReadMemory(xml, xml_size, NULL, NULL, 0);
if (!xmldoc || (xmlroot = xmlDocGetRootElement(xmldoc)) == NULL) {
xmlFreeDoc(xmldoc);
@@ -91,6 +91,26 @@ Datum ST_GeomFromMARC21(PG_FUNCTION_ARGS) {
PG_RETURN_POINTER(geom);
}
+static inline bool
+is_xml_element(xmlNodePtr xn, const char *xml_name)
+{
+ char *colon_pos, *node_name;
+
+ /* Not an element node, can't do anything */
+ if (!xn || xn->type != XML_ELEMENT_NODE)
+ return false;
+
+ /* If there's a colon in the element name, */
+ /* move past it before checking for equality with */
+ /* the element name we are looking for */
+ node_name = (char*)xn->name;
+ colon_pos = strchr(node_name, ':');
+ if (colon_pos)
+ node_name = colon_pos + 1;
+
+ return strcmp(node_name, xml_name) == 0;
+}
+
static int is_literal_valid(const char *literal) {
int num_dec_sep;
@@ -381,7 +401,8 @@ parse_marc21(xmlNodePtr xnode) {
* https://www.loc.gov/standards/marcxml/xml/spy/spy.html
*/
- if (xmlStrcmp(xnode->name, (xmlChar*) "record")) lwpgerror("invalid MARC21/XML document. Root element <record> expected but <%s> found.",xnode->name);
+ if (!is_xml_element(xnode, "record"))
+ lwpgerror("invalid MARC21/XML document. Root element <record> expected but <%s> found.",xnode->name);
result_type = 0;
ngeoms = 0;
@@ -395,18 +416,23 @@ parse_marc21(xmlNodePtr xnode) {
if (datafield->type != XML_ELEMENT_NODE) continue;
- if (xmlStrcmp(datafield->name, (xmlChar*) "datafield") != 0 || xmlStrcmp(xmlGetProp(datafield, (xmlChar*) "tag"),(xmlChar*) "034") != 0) continue;
+ if (!is_xml_element(datafield, "datafield") || xmlStrcmp(xmlGetProp(datafield, (xmlChar*) "tag"),(xmlChar*) "034") != 0) continue;
POSTGIS_DEBUG(3, " datafield found");
for (subfield = datafield->children; subfield != NULL; subfield = subfield->next) {
if (subfield->type != XML_ELEMENT_NODE) continue;
- if (xmlStrcmp(subfield->name, (xmlChar*) "subfield") != 0) continue;
+ if (!is_xml_element(subfield, "subfield"))
+ continue;
code = (char*) xmlGetProp(subfield, (xmlChar*) "code");
- if ((strcmp(code, "d") != 0 && strcmp(code, "e") != 0 && strcmp(code, "f") != 0 && strcmp(code, "g")) != 0) continue;
+ if ((strcmp(code, "d") != 0 &&
+ strcmp(code, "e") != 0 &&
+ strcmp(code, "f") != 0 &&
+ strcmp(code, "g")) != 0)
+ continue;
literal = (char*) xmlNodeGetContent(subfield);
@@ -437,7 +463,8 @@ parse_marc21(xmlNodePtr xnode) {
double s = parse_geo_literal(ls);
geometry_type = 0;
- if (ngeoms > 0) lwgeoms = (LWGEOM**) lwrealloc(lwgeoms, sizeof(LWGEOM*) * (ngeoms + 1));
+ if (ngeoms > 0) lwgeoms = (LWGEOM**)
+ lwrealloc(lwgeoms, sizeof(LWGEOM*) * (ngeoms + 1));
if (fabs(w - e) < 0.0000001f && fabs(n - s) < 0.0000001f) {
diff --git a/regress/core/in_gml.sql b/regress/core/in_gml.sql
index 534e79e7f..cfdb1b5a3 100644
--- a/regress/core/in_gml.sql
+++ b/regress/core/in_gml.sql
@@ -706,7 +706,7 @@ SELECT 'ns_8', ST_AsEWKT(ST_GeomFromGML('<gml:Point gml:srsName="EPSG:4326" xmln
SELECT 'ns_9', ST_AsEWKT(ST_GeomFromGML('<gml:Point gml:srsName="EPSG:4326" xmlns:gml="http://www.opengis.net/gml/3.2"><gml:coordinates>1,2</gml:coordinates></gml:Point>'));
-- Attribute with explicit prefix but unqualified namespace
-SELECT 'ns_10', ST_AsEWKT(ST_GeomFromGML('<gml:Point foo:srsName="EPSG:4326" xmlns:gml="http://www.opengis.net/gml"><gml:coordinates>1,2</gml:coordinates></gml:Point>'));
+SELECT 'ns_10', ST_AsEWKT(ST_GeomFromGML('<gml:Point srsName="EPSG:4326" xmlns:gml="http://www.opengis.net/gml"><gml:coordinates>1,2</gml:coordinates></gml:Point>'));
-- Ignore other namespace attribute
SELECT 'ns_11', ST_AsEWKT(ST_GeomFromGML('<gml:Point foo:srsName="EPSG:4326" xmlns:foo="http://foo.net" xmlns:gml="http://www.opengis.net/gml"><gml:coordinates>1,2</gml:coordinates><foo:coordinates>3,4</foo:coordinates></gml:Point>'));
-----------------------------------------------------------------------
Summary of changes:
postgis/lwgeom_in_gml.c | 183 ++++++++++++++++++++++++++-------------------
postgis/lwgeom_in_kml.c | 51 +++++++++----
postgis/lwgeom_in_marc21.c | 39 ++++++++--
regress/core/in_gml.sql | 2 +-
4 files changed, 177 insertions(+), 98 deletions(-)
hooks/post-receive
--
PostGIS
More information about the postgis-tickets
mailing list