remove invalid characters <32 from XML output
[planetdump.git] / output_osm.c
index bc384e1..cc22f22 100644 (file)
@@ -29,7 +29,7 @@ const char *xmlescape(const char *in)
     // To fix this we'd need to fix the DB output parameters too
 #ifdef USE_ICONV 
     if (cd != ICONV_ERROR) {
-        char iconv_tmp[1024];
+        char iconv_tmp[2048];
         char *inbuf = in, *outbuf = iconv_tmp;
         size_t ret;
         size_t inlen = strlen(inbuf);
@@ -66,7 +66,13 @@ const char *xmlescape(const char *in)
         } else if (*in == '"') {
             strcpy(&escape_tmp[len], "&quot;");
             len += strlen("&quot;");
+        } else if ((*in == 9) || (*in == 10) || (*in == 13)) {
+            len+=sprintf(&escape_tmp[len], "&#%d;", *in);
         } else if ((*in >= 0) && (*in < 32)) {
+           /* These characters are not valid in XML output
+            * http://www.w3.org/TR/REC-xml/#NT-Char
+            * (tab, newline, carriage return are handled above)
+            */
             escape_tmp[len] = '?';
             len++;
         } else {
@@ -93,6 +99,30 @@ void osm_tags(struct keyval *tags)
    resetList(tags);
 }
 
+void osm_changeset(int id, const char *user, const char *created_at, const char *closed_at, 
+           int num_changes, int has_bbox, 
+                  long double min_lat, long double max_lat, long double min_lon, long double max_lon, 
+                  int open, struct keyval *tags) {
+  printf(INDENT "<changeset id=\"%d\" created_at=\"%s\" num_changes=\"%d\" ", id, created_at, num_changes);
+  if (open) {
+    printf("open=\"true\" ");
+  } else {
+    printf("closed_at=\"%s\" open=\"false\" ", closed_at);
+  }
+  if (has_bbox) {
+    printf("min_lon=\"%.7Lf\" min_lat=\"%.7Lf\" max_lon=\"%.7Lf\" max_lat=\"%.7Lf\" ",
+          min_lon, min_lat, max_lon, max_lat);
+  }
+  printf("%s", user);
+  if (listHasData(tags)) {
+    printf(">\n");
+    osm_tags(tags);
+    printf(INDENT "</changeset>\n");
+  } else {
+    printf("/>\n");
+  }
+}
+
 void osm_node(int id, long double lat, long double lon, struct keyval *tags, const char *ts, const char *user, int version, int changeset)
 {
   if (listHasData(tags)) {
@@ -132,10 +162,12 @@ void osm_relation(int id, struct keyval *members, struct keyval *roles, struct k
   if (listHasData(tags) || listHasData(members)) {
     printf(INDENT "<relation id=\"%d\" timestamp=\"%s\" version=\"%d\" changeset=\"%d\"%s>\n", id, ts, version, changeset, user);
     while (((p = popItem(members)) != NULL) && ((q = popItem(roles)) != NULL)) {
-      const char *m_type = p->key;
+      char *m_type = p->key;
+      char *i; 
+      for (i = m_type; *i; i++) *i = tolower(*i);
       const char *m_id   = p->value;
       const char *m_role = q->value;
-      printf(INDENT INDENT "<member type=\"%s\" ref=\"%s\" role=\"%s\"/>\n", m_type, m_id, m_role);
+      printf(INDENT INDENT "<member type=\"%s\" ref=\"%s\" role=\"%s\"/>\n", m_type, m_id, xmlescape(m_role));
       freeItem(p);
       freeItem(q);
     }