Yog.IO.GraphML (YogEx v1.0.0)

Copy Markdown View Source

GraphML (Graph Markup Language) serialization support.

Provides functions to serialize and deserialize graphs in the GraphML format, an XML-based format widely supported by graph visualization and analysis tools like Gephi, yEd, Cytoscape, and NetworkX.

Format Overview

GraphML is an XML-based format that supports:

  • Nodes with custom attributes
  • Edges with custom attributes
  • Directed and undirected graphs
  • Hierarchical graphs (not yet supported)

Performance

For optimal performance with large GraphML files, add the optional saxy dependency to your project:

{:saxy, "~> 1.5"}

When available, saxy provides a fast streaming SAX parser that significantly improves loading times:

  • Without saxy: Uses Erlang's :xmerl (DOM parser, slower for large files)
  • With saxy: Uses streaming parser (up to 3-4x faster for large files)

Examples

Basic Serialization and Deserialization

iex> graph = Yog.directed()
...> |> Yog.add_node(1, "Alice")
...> |> Yog.add_node(2, "Bob")
...> |> Yog.add_edge_ensure(from: 1, to: 2, with: "friend")
iex> xml = Yog.IO.GraphML.serialize(graph)
iex> String.contains?(xml, "Alice")
true
iex> String.contains?(xml, "Bob")
true

Custom Attributes with Type Information

iex> graph = Yog.directed()
...> |> Yog.add_node(1, %{name: "Alice", age: 30})
...> |> Yog.add_node(2, %{name: "Bob", age: 25})
...> |> Yog.add_edge_ensure(from: 1, to: 2, with: %{weight: 5, relation: "friend"})
iex> node_attr = fn data ->
...>   %{"label" => data.name, "age" => Integer.to_string(data.age)}
...> end
iex> edge_attr = fn data ->
...>   %{"weight" => Integer.to_string(data.weight), "type" => data.relation}
...> end
iex> xml = Yog.IO.GraphML.serialize_with(node_attr, edge_attr, graph)
iex> String.contains?(xml, "Alice")
true

Reading from File

# Read a GraphML file from disk
{:ok, graph} = Yog.IO.GraphML.read("network.graphml")

Writing to File

# Write with default string conversion
Yog.IO.GraphML.write("output.graphml", graph)

Summary

Functions

Returns default GraphML serialization options.

Deserializes a GraphML string to a graph using default conversion.

Deserializes a GraphML string into a graph with custom data mappers.

Creates GraphML options with custom formatting.

Reads a graph from a GraphML file using default conversion.

Reads a graph from a GraphML file with custom data mappers.

Serializes a graph to GraphML string using default attribute conversion.

Serializes a graph to GraphML string with custom attribute mappers.

Serializes a graph to a GraphML string with custom options.

Serializes a graph to GraphML with typed attributes for Gephi compatibility.

Serializes a graph to GraphML with typed attributes and custom options.

Writes a graph to a GraphML file using default attribute conversion.

Writes a graph to a GraphML file with custom attribute mappers.

Writes a graph to a GraphML file with typed attributes for Gephi compatibility.

Functions

default_options()

@spec default_options() :: tuple()

Returns default GraphML serialization options.

Time complexity: $\mathcal{O}(1)$

deserialize(xml)

@spec deserialize(String.t()) :: {:ok, Yog.graph()} | {:error, term()}

Deserializes a GraphML string to a graph using default conversion.

Raises ArgumentError if xml is not a binary string.

Time complexity: $\mathcal{O}(V + E)$

deserialize_with(node_folder, edge_folder, xml)

@spec deserialize_with((map() -> any()), (map() -> any()), String.t()) ::
  {:ok, Yog.graph()} | {:error, term()}

Deserializes a GraphML string into a graph with custom data mappers.

Raises ArgumentError if xml or data mappers are invalid.

Time complexity: $\mathcal{O}(V + E)$

options_with(indent, include_declaration, opts \\ [])

@spec options_with(non_neg_integer(), boolean(), keyword()) :: tuple()

Creates GraphML options with custom formatting.

Raises ArgumentError if parameters are invalid.

Time complexity: $\mathcal{O}(1)$

read(path)

@spec read(String.t()) :: {:ok, Yog.graph()} | {:error, term()}

Reads a graph from a GraphML file using default conversion.

Raises ArgumentError if path is not a binary string.

Time complexity: $\mathcal{O}(V + E)$ + file I/O

read_with(path, node_folder, edge_folder)

@spec read_with(String.t(), (map() -> any()), (map() -> any())) ::
  {:ok, Yog.graph()} | {:error, term()}

Reads a graph from a GraphML file with custom data mappers.

Raises ArgumentError if path is not a binary string or mappers are invalid.

Time complexity: $\mathcal{O}(V + E)$ + file I/O

serialize(graph)

@spec serialize(Yog.graph() | Yog.DAG.t()) :: String.t()

Serializes a graph to GraphML string using default attribute conversion.

Raises ArgumentError if graph is invalid.

Time complexity: $\mathcal{O}(V + E)$

serialize_with(node_attr, edge_attr, graph)

@spec serialize_with((any() -> map()), (any() -> map()), Yog.graph() | Yog.DAG.t()) ::
  String.t()

Serializes a graph to GraphML string with custom attribute mappers.

Raises ArgumentError if mappers or graph are invalid.

Time complexity: $\mathcal{O}(V + E)$

serialize_with_options(node_attr, edge_attr, options, graph)

@spec serialize_with_options(
  (any() -> map()),
  (any() -> map()),
  tuple(),
  Yog.graph() | Yog.DAG.t()
) ::
  String.t()

Serializes a graph to a GraphML string with custom options.

Raises ArgumentError if arguments or options are invalid.

Time complexity: $\mathcal{O}(V + E)$

serialize_with_types(node_attr, edge_attr, graph)

@spec serialize_with_types(
  (any() -> map()),
  (any() -> map()),
  Yog.graph() | Yog.DAG.t()
) :: String.t()

Serializes a graph to GraphML with typed attributes for Gephi compatibility.

Raises ArgumentError if mappers or graph are invalid.

Time complexity: $\mathcal{O}(V + E)$

serialize_with_types_and_options(node_attr, edge_attr, options, graph)

@spec serialize_with_types_and_options(
  (any() -> map()),
  (any() -> map()),
  tuple(),
  Yog.graph() | Yog.DAG.t()
) :: String.t()

Serializes a graph to GraphML with typed attributes and custom options.

Raises ArgumentError if arguments or options are invalid.

Time complexity: $\mathcal{O}(V + E)$

write(path, graph)

@spec write(String.t(), Yog.graph() | Yog.DAG.t()) :: {:ok, nil} | {:error, atom()}

Writes a graph to a GraphML file using default attribute conversion.

Raises ArgumentError if path is not a binary string or graph is invalid.

Time complexity: $\mathcal{O}(V + E)$ + file I/O

write_with(path, node_attr, edge_attr, graph)

@spec write_with(
  String.t(),
  (any() -> map()),
  (any() -> map()),
  Yog.graph() | Yog.DAG.t()
) ::
  {:ok, nil} | {:error, atom()}

Writes a graph to a GraphML file with custom attribute mappers.

Raises ArgumentError if path is not a binary string or graph/mappers are invalid.

Time complexity: $\mathcal{O}(V + E)$ + file I/O

write_with_types(path, node_attr, edge_attr, graph)

@spec write_with_types(
  String.t(),
  (any() -> map()),
  (any() -> map()),
  Yog.graph() | Yog.DAG.t()
) ::
  {:ok, nil} | {:error, atom()}

Writes a graph to a GraphML file with typed attributes for Gephi compatibility.

Raises ArgumentError if path is not a binary string or graph/mappers are invalid.

Time complexity: $\mathcal{O}(V + E)$ + file I/O