Skip to content

Commit

Permalink
Use XML 1.0; resolves #26. (#41)
Browse files Browse the repository at this point in the history
- Roll back to XML 1.0 from 1.1 introduced in
d17b57c
- Roll back to Gexf 1.2 from 1.3 introduced in
d17b57c
- Switch line ending encoding from \n to \x0A
- Clean up whitespace in file
  • Loading branch information
ruebot authored and greebie committed Aug 28, 2018
1 parent 050127b commit d03c01a
Showing 1 changed file with 72 additions and 72 deletions.
144 changes: 72 additions & 72 deletions src/gexf.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
// Copyright © 2018 Ryan Deschamps. All rights reserved.
//

/** @file gexf.c
/** @file gexf.c
@brief Writes gexf files.
*/

Expand Down Expand Up @@ -48,10 +48,10 @@ int igraph_i_xml_escape(char* src, char** dest) {
}

/** Writes a GEXF file
GEXF provides great support for visualizations and is therefore used by a number
of light-weight visualization tools like SigmaJS and Gephi.
@param graph - the graph to write to gexf
@param outstream - a file object
@param prefixattr - if "true" will add prefixes to the gexf output.
Expand All @@ -72,37 +72,37 @@ extern int igraph_write_graph_gexf(const igraph_t *graph, FILE *outstream,
const char *gprefix= prefixattr ? "g_" : "";
const char *vprefix= prefixattr ? "v_" : "";
const char *eprefix= prefixattr ? "e_" : "";
ret=fprintf(outstream, "<?xml version=\"1.1\" encoding=\"UTF-8\"?>\n");

ret=fprintf(outstream, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\x0A");
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);
ret=fprintf(outstream, "<gexf xmlns=\"http://www.gexf.net/1.3draft\"\n");
ret=fprintf(outstream, "<gexf xmlns=\"http://www.gexf.net/1.2draft\"\x0A");
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);
ret=fprintf(outstream, " xmlns:viz=\"http://www.gexf.net/1.3draft/viz\"\n");
ret=fprintf(outstream, " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n");
ret=fprintf(outstream, " xmlns:viz=\"http://www.gexf.net/1.2draft/viz\"\x0A");
ret=fprintf(outstream, " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\x0A");
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);
ret=fprintf(outstream, " xsi:schemaLocation=\"http://www.gexf.net/1.3draft\n");
ret=fprintf(outstream, " xsi:schemaLocation=\"http://www.gexf.net/1.2draft\x0A");
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);
ret=fprintf(outstream, " http://www.gexf.net/1.3draft/gexf.xsd\"\n");
ret=fprintf(outstream, " http://www.gexf.net/1.2draft/gexf.xsd\"\x0A");
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);
ret=fprintf(outstream, " version=\"1.3\">\n");
ret=fprintf(outstream, " version=\"1.2\">\x0A");
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);
ret=fprintf(outstream, "<!-- Created by igraph -->\n");
ret=fprintf(outstream, "<!-- Created by igraph -->\x0A");
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);
ret=fprintf(outstream, "<meta lastmodifieddate=\"%.19s\">\n", ctime(&t));
ret=fprintf(outstream, "<meta lastmodifieddate=\"%.19s\">\x0A", ctime(&t));
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);
ret=fprintf(outstream, "<creator>Graphpass filtering using Igraph by Archives Unleashed</creator>\n");
ret=fprintf(outstream, "<creator>Graphpass filtering using Igraph by Archives Unleashed</creator>\x0A");
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);
ret=fprintf(outstream, "<description> A Filtered Derivative Graph</description>\n");
ret=fprintf(outstream, "<description> A Filtered Derivative Graph</description>\x0A");
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);
ret=fprintf(outstream, "</meta>\n");
ret=fprintf(outstream, "</meta>\x0A");
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);

/* dump the <key> elements if any */

IGRAPH_VECTOR_INIT_FINALLY(&numv, 1);
IGRAPH_STRVECTOR_INIT_FINALLY(&strv, 1);
IGRAPH_VECTOR_BOOL_INIT_FINALLY(&boolv, 1);

IGRAPH_STRVECTOR_INIT_FINALLY(&gnames, 0);
IGRAPH_STRVECTOR_INIT_FINALLY(&vnames, 0);
IGRAPH_STRVECTOR_INIT_FINALLY(&enames, 0);
Expand All @@ -113,77 +113,77 @@ extern int igraph_write_graph_gexf(const igraph_t *graph, FILE *outstream,
&gnames, &gtypes,
&vnames, &vtypes,
&enames, &etypes);
ret=fprintf(outstream, " <graph id=\"G\" defaultedgetype=\"%s\">\n", (igraph_is_directed(graph)?"directed":"undirected"));

ret=fprintf(outstream, " <graph id=\"G\" defaultedgetype=\"%s\">\x0A", (igraph_is_directed(graph)?"directed":"undirected"));
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);

/* graph attributes */
ret=fprintf(outstream, " <attributes class=\"graph\">\n");
ret=fprintf(outstream, " <attributes class=\"graph\">\x0A");
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);
for (i=0; i<igraph_vector_size(&gtypes); i++) {
char *name, *name_escaped;
igraph_strvector_get(&gnames, i, &name);
IGRAPH_CHECK(igraph_i_xml_escape(name, &name_escaped));
if (VECTOR(gtypes)[i] == IGRAPH_ATTRIBUTE_STRING) {
ret=fprintf(outstream, " <attribute id=\"%s%s\" title=\"%s\" type=\"string\"/>\n", gprefix, name_escaped, name_escaped);
ret=fprintf(outstream, " <attribute id=\"%s%s\" title=\"%s\" type=\"string\"/>\x0A", gprefix, name_escaped, name_escaped);
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);
} else if (VECTOR(gtypes)[i] == IGRAPH_ATTRIBUTE_NUMERIC) {
ret=fprintf(outstream, " <attribute id=\"%s%s\" title=\"%s\" type=\"double\"/>\n", gprefix, name_escaped, name_escaped);
ret=fprintf(outstream, " <attribute id=\"%s%s\" title=\"%s\" type=\"double\"/>\x0A", gprefix, name_escaped, name_escaped);
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);
} else if (VECTOR(gtypes)[i] == IGRAPH_ATTRIBUTE_BOOLEAN) {
ret=fprintf(outstream, " <attribute id=\"%s%s\" attr.title=\"%s\" type=\"boolean\"/>\n", gprefix, name_escaped, name_escaped);
ret=fprintf(outstream, " <attribute id=\"%s%s\" attr.title=\"%s\" type=\"boolean\"/>\x0A", gprefix, name_escaped, name_escaped);
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);
}
igraph_Free(name_escaped);
}
ret=fprintf(outstream, " </attributes>\n");
ret=fprintf(outstream, " </attributes>\x0A");
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);

/* vertex attributes */
ret=fprintf(outstream, " <attributes class=\"node\">\n");
ret=fprintf(outstream, " <attributes class=\"node\">\x0A");
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);

for (i=0; i<igraph_vector_size(&vtypes); i++) {
char *name, *name_escaped;
igraph_strvector_get(&vnames, i, &name);
IGRAPH_CHECK(igraph_i_xml_escape(name, &name_escaped));
if (VECTOR(vtypes)[i] == IGRAPH_ATTRIBUTE_STRING) {
ret=fprintf(outstream, " <attribute id=\"%s%s\" title=\"%s\" type=\"string\"></attribute>\n", vprefix, name_escaped, name_escaped);
ret=fprintf(outstream, " <attribute id=\"%s%s\" title=\"%s\" type=\"string\"></attribute>\x0A", vprefix, name_escaped, name_escaped);
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);
} else if (VECTOR(vtypes)[i] == IGRAPH_ATTRIBUTE_NUMERIC) {
ret=fprintf(outstream, " <attribute id=\"%s%s\" title=\"%s\" type=\"double\"></attribute>\n", vprefix, name_escaped, name_escaped);
ret=fprintf(outstream, " <attribute id=\"%s%s\" title=\"%s\" type=\"double\"></attribute>\x0A", vprefix, name_escaped, name_escaped);
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);
} else if (VECTOR(vtypes)[i] == IGRAPH_ATTRIBUTE_BOOLEAN) {
ret=fprintf(outstream, " <attribute id=\"%s%s\" title=\"%s\" type=\"boolean\"></attribute>\n", vprefix, name_escaped, name_escaped);
ret=fprintf(outstream, " <attribute id=\"%s%s\" title=\"%s\" type=\"boolean\"></attribute>\x0A", vprefix, name_escaped, name_escaped);
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);
}
igraph_Free(name_escaped);
}
ret=fprintf(outstream, " </attributes>\n");
ret=fprintf(outstream, " </attributes>\x0A");
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);

/* edge attributes */
ret=fprintf(outstream, " <attributes class=\"edge\">\n");
ret=fprintf(outstream, " <attributes class=\"edge\">\x0A");
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);
for (i=0; i<igraph_vector_size(&etypes); i++) {
char *name, *name_escaped;
igraph_strvector_get(&enames, i, &name);
IGRAPH_CHECK(igraph_i_xml_escape(name, &name_escaped));
if (VECTOR(etypes)[i] == IGRAPH_ATTRIBUTE_STRING) {
ret=fprintf(outstream, " <attribute id=\"%s%s\" title=\"%s\" type=\"string\"/>\n", eprefix, name_escaped, name_escaped);
ret=fprintf(outstream, " <attribute id=\"%s%s\" title=\"%s\" type=\"string\"/>\x0A", eprefix, name_escaped, name_escaped);
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);
} else if (VECTOR(etypes)[i] == IGRAPH_ATTRIBUTE_NUMERIC) {
ret=fprintf(outstream, " <attribute id=\"%s%s\" title=\"%s\" type=\"double\"/>\n", eprefix, name_escaped, name_escaped);
ret=fprintf(outstream, " <attribute id=\"%s%s\" title=\"%s\" type=\"double\"/>\x0A", eprefix, name_escaped, name_escaped);
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);
} else if (VECTOR(etypes)[i] == IGRAPH_ATTRIBUTE_BOOLEAN) {
ret=fprintf(outstream, " <attribute id=\"%s%s\" title=\"%s\" type=\"boolean\"/>\n", eprefix, name_escaped, name_escaped);
ret=fprintf(outstream, " <attribute id=\"%s%s\" title=\"%s\" type=\"boolean\"/>\x0A", eprefix, name_escaped, name_escaped);
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);
}
igraph_Free(name_escaped);
}
ret=fprintf(outstream, " </attributes>\n");
ret=fprintf(outstream, " </attributes>\x0A");
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);

/* Do not include graph attvalues for now but can add them later */
/*
for (i=0; i<igraph_vector_size(&gtypes); i++) {
Expand Down Expand Up @@ -223,9 +223,9 @@ extern int igraph_write_graph_gexf(const igraph_t *graph, FILE *outstream,
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);
}
}*/

/* Let's dump the nodes first */
ret=fprintf(outstream, " <nodes>\n");
ret=fprintf(outstream, " <nodes>\x0A");
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);
vc=igraph_vcount(graph);
ec=igraph_ecount(graph);
Expand All @@ -237,7 +237,7 @@ extern int igraph_write_graph_gexf(const igraph_t *graph, FILE *outstream,
igraph_vector_init(&y, vc);
igraph_vector_init(&x, vc);
igraph_vector_init(&size, vc);

if (igraph_cattribute_has_attr(graph, IGRAPH_ATTRIBUTE_EDGE, "weight") == true) {
EANV(graph, "weight", &weight);
}
Expand All @@ -249,7 +249,7 @@ extern int igraph_write_graph_gexf(const igraph_t *graph, FILE *outstream,
} else {
printf ("No label information available on this graph.");
}

/*if ( VASV(graph, "label", &label) == 0 ){
VASV(graph, "label", &label);
} else if (VASV(graph, "name", &label) == 0) {
Expand All @@ -267,9 +267,9 @@ extern int igraph_write_graph_gexf(const igraph_t *graph, FILE *outstream,
char *name, *name_escaped, *label, *label_escaped;
igraph_strvector_get(&labels, l, &label);
IGRAPH_CHECK(igraph_i_xml_escape(label, &label_escaped));
ret=fprintf(outstream, " <node id=\"n%ld\" label=\"%s\">\n", (long)l, label_escaped ? label_escaped : "x");
ret=fprintf(outstream, " <node id=\"n%ld\" label=\"%s\">\x0A", (long)l, label_escaped ? label_escaped : "x");
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);
ret=fprintf(outstream, " <attvalues>\n");
ret=fprintf(outstream, " <attvalues>\x0A");
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);
for (i=0; i<igraph_vector_size(&vtypes); i++) {
if (VECTOR(vtypes)[i] == IGRAPH_ATTRIBUTE_NUMERIC) {
Expand All @@ -278,7 +278,7 @@ extern int igraph_write_graph_gexf(const igraph_t *graph, FILE *outstream,
igraph_vss_1(l), &numv));
if (!isnan(VECTOR(numv)[0])) {
IGRAPH_CHECK(igraph_i_xml_escape(name, &name_escaped));
ret=fprintf(outstream, " <attvalue for=\"%s%s\" value=\"%g\" />\n",
ret=fprintf(outstream, " <attvalue for=\"%s%s\" value=\"%g\" />\x0A",
vprefix, name_escaped, VECTOR(numv)[0]);
igraph_Free(name_escaped);
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);
Expand All @@ -294,36 +294,36 @@ extern int igraph_write_graph_gexf(const igraph_t *graph, FILE *outstream,
igraph_vss_1(l), &strv));
igraph_strvector_get(&strv, 0, &s);
IGRAPH_CHECK(igraph_i_xml_escape(s, &s_escaped));
ret=fprintf(outstream, "%s\" />\n", s_escaped);
ret=fprintf(outstream, "%s\" />\x0A", s_escaped);
igraph_Free(s_escaped);
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);
} else if (VECTOR(vtypes)[i] == IGRAPH_ATTRIBUTE_BOOLEAN) {
igraph_strvector_get(&vnames, i, &name);
IGRAPH_CHECK(igraph_i_attribute_get_bool_vertex_attr(graph, name,
igraph_vss_1(l), &boolv));
IGRAPH_CHECK(igraph_i_xml_escape(name, &name_escaped));
ret=fprintf(outstream, " <attvalue for=\"%s%s\" value=\"%s\" />\n",
ret=fprintf(outstream, " <attvalue for=\"%s%s\" value=\"%s\" />\x0A",
vprefix, name_escaped, VECTOR(boolv)[0] ? "true" : "false");
igraph_Free(name_escaped);
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);
}
}
ret=fprintf(outstream, " </attvalues>\n");
ret=fprintf(outstream, " </attvalues>\x0A");
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);
ret=fprintf(outstream, " <viz:color r=\"%i\" g=\"%i\" b=\"%i\"></viz:color>\n", (int)VECTOR(r)[l], (int)VECTOR(g)[l], (int)VECTOR(b)[l]);
ret=fprintf(outstream, " <viz:color r=\"%i\" g=\"%i\" b=\"%i\"></viz:color>\x0A", (int)VECTOR(r)[l], (int)VECTOR(g)[l], (int)VECTOR(b)[l]);
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);
ret=fprintf(outstream, " <viz:size value=\"%f\"></viz:size>\n", VECTOR(size)[l]);
ret=fprintf(outstream, " <viz:size value=\"%f\"></viz:size>\x0A", VECTOR(size)[l]);
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);
ret=fprintf(outstream, " <viz:position y=\"%f\" x=\"%f\" z=\"0.0\"></viz:position>\n", VECTOR(y)[l], VECTOR(x)[l]);
ret=fprintf(outstream, " <viz:position y=\"%f\" x=\"%f\" z=\"0.0\"></viz:position>\x0A", VECTOR(y)[l], VECTOR(x)[l]);
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);
ret=fprintf(outstream, " </node>\n");
ret=fprintf(outstream, " </node>\x0A");
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);
}
ret=fprintf(outstream, " </nodes>\n");
ret=fprintf(outstream, " </nodes>\x0A");
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);

/* Now the edges */
ret=fprintf(outstream, " <edges>\n");
ret=fprintf(outstream, " <edges>\x0A");
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);
IGRAPH_CHECK(igraph_eit_create(graph, igraph_ess_all(0), &it));
IGRAPH_FINALLY(igraph_eit_destroy, &it);
Expand All @@ -332,20 +332,20 @@ extern int igraph_write_graph_gexf(const igraph_t *graph, FILE *outstream,
char *name, *name_escaped;
long int edge=IGRAPH_EIT_GET(it);
igraph_edge(graph, (igraph_integer_t) edge, &from, &to);
ret=fprintf(outstream, " <edge id=\"%ld\" source=\"n%ld\" target=\"n%ld\" weight=\"%f\">\n",
ret=fprintf(outstream, " <edge id=\"%ld\" source=\"n%ld\" target=\"n%ld\" weight=\"%f\">\x0A",
(long int)l, (long int)from, (long int)to, VECTOR(weight)[l] ? VECTOR(weight)[l] : 0.0);
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);
ret=fprintf(outstream, " <attvalues>\n");
ret=fprintf(outstream, " <attvalues>\x0A");
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);

for (i=0; i<igraph_vector_size(&etypes); i++) {
if (VECTOR(etypes)[i] == IGRAPH_ATTRIBUTE_NUMERIC) {
igraph_strvector_get(&enames, i, &name);
IGRAPH_CHECK(igraph_i_attribute_get_numeric_edge_attr(graph, name,
igraph_ess_1((igraph_integer_t) edge), &numv));
if (!isnan(VECTOR(numv)[0])) {
IGRAPH_CHECK(igraph_i_xml_escape(name, &name_escaped));
ret=fprintf(outstream, " <attvalue for=\"%s%s\" value=\"%g\"></attvalue>\n",
ret=fprintf(outstream, " <attvalue for=\"%s%s\" value=\"%g\"></attvalue>\x0A",
eprefix, name_escaped, VECTOR(numv)[0]);
igraph_Free(name_escaped);
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);
Expand All @@ -361,36 +361,36 @@ extern int igraph_write_graph_gexf(const igraph_t *graph, FILE *outstream,
igraph_ess_1((igraph_integer_t) edge), &strv));
igraph_strvector_get(&strv, 0, &s);
IGRAPH_CHECK(igraph_i_xml_escape(s, &s_escaped));
ret=fprintf(outstream, "%s\"></attvalue>\n", s_escaped);
ret=fprintf(outstream, "%s\"></attvalue>\x0A", s_escaped);
igraph_Free(s_escaped);
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);
} else if (VECTOR(etypes)[i] == IGRAPH_ATTRIBUTE_BOOLEAN) {
igraph_strvector_get(&enames, i, &name);
IGRAPH_CHECK(igraph_i_attribute_get_bool_edge_attr(graph, name,
igraph_ess_1((igraph_integer_t) edge), &boolv));
IGRAPH_CHECK(igraph_i_xml_escape(name, &name_escaped));
ret=fprintf(outstream, " <attvalue for=\"%s%s\" value\"%s\"></attvalue>\n",
ret=fprintf(outstream, " <attvalue for=\"%s%s\" value\"%s\"></attvalue>\x0A",
eprefix, name_escaped, VECTOR(boolv)[0] ? "true" : "false");
igraph_Free(name_escaped);
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);
}
}
ret=fprintf(outstream, " </attvalues>\n");
ret=fprintf(outstream, " </attvalues>\x0A");
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);
ret=fprintf(outstream, " </edge>\n");
ret=fprintf(outstream, " </edge>\x0A");
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);
IGRAPH_EIT_NEXT(it);
}
ret=fprintf(outstream, " </edges>\n");
ret=fprintf(outstream, " </edges>\x0A");
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);
igraph_eit_destroy(&it);
IGRAPH_FINALLY_CLEAN(1);
ret=fprintf(outstream, " </graph>\n");

ret=fprintf(outstream, " </graph>\x0A");
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);
fprintf(outstream, "</gexf>\n");
fprintf(outstream, "</gexf>\x0A");
if (ret<0) IGRAPH_ERROR("Write failed", IGRAPH_EFILE);

igraph_strvector_destroy(&gnames);
igraph_strvector_destroy(&vnames);
igraph_strvector_destroy(&enames);
Expand All @@ -401,6 +401,6 @@ extern int igraph_write_graph_gexf(const igraph_t *graph, FILE *outstream,
igraph_strvector_destroy(&strv);
igraph_vector_bool_destroy(&boolv);
IGRAPH_FINALLY_CLEAN(9);

return 0;
}

0 comments on commit d03c01a

Please sign in to comment.