# How xlabel and label Are Handled Differently for Edges in graphviz2drawio

> **In graphviz2drawio, `xlabel` takes precedence over `label` when constructing lookup keys for edge attribute enrichment, while the visual text rendered on edges is extracted independently from SVG `<text>` elements.**

- Repository: [Harold Martin/graphviz2drawio](https://github.com/hbmartin/graphviz2drawio)
- Tags: deep-dive
- Published: 2026-03-03

---

**In graphviz2drawio, `xlabel` takes precedence over `label` when constructing lookup keys for edge attribute enrichment, while the visual text rendered on edges is extracted independently from SVG `<text>` elements.**

The `hbmartin/graphviz2drawio` converter processes Graphviz DOT files by rendering them to SVG, then parsing that SVG to generate Draw.io diagrams. During this pipeline, edge attributes require special handling to map pygraphviz properties onto the visual elements, which creates a distinct separation between how `xlabel` and `label` influence the enrichment process versus the visual output.

## Lookup Key Construction: xlabel Precedence

When building the internal attribute map, the converter prioritizes `xlabel` over `label` to create unique dictionary keys for each edge. In [`graphviz2drawio.py`](https://github.com/hbmartin/graphviz2drawio/blob/main/graphviz2drawio.py) at lines 19‑24, the code constructs the lookup key using a fallback chain that checks `xlabel` first:

```python
graph_edges = {
    f"{e[0]}->{e[1]}-" 
    + (e.attr.get("xlabel") or e.attr.get("label") or ""): e.attr.to_dict()
    for e in graph.edges_iter()
}

```

This logic ensures that if an edge possesses both attributes, the `xlabel` value becomes the distinguishing component of the key. Consequently, two edges with identical source, destination, and `label` values—but different `xlabel` values—receive distinct entries in the `graph_edges` dictionary, enabling separate attribute enrichment for each.

## Visual Label Extraction from SVG

The actual text displayed on the diagram originates from the SVG rendering rather than the pygraphviz attributes directly. The `EdgeFactory.from_svg` method in [`mx/EdgeFactory.py`](https://github.com/hbmartin/graphviz2drawio/blob/main/mx/EdgeFactory.py) (lines 25‑30) parses the `<g class="edge">` groups to collect all `<text>` elements:

```python
labels: list[Text] = [
    text_from_tag
    for tag in g
    if SVG.is_tag(tag, "text")
    and (text_from_tag := Text.from_svg(tag)) is not None
]

```

These `Text` objects represent the rendered visual labels and are stored in the edge's `labels` property. This extraction process operates independently of whether the original Graphviz attribute was `xlabel` or `label`, meaning the visual content depends entirely on what Graphviz rendered into the SVG.

## Edge Enrichment and Key Matching

After SVG parsing, the converter enriches edge objects with their original pygraphviz attributes by matching the visual labels back to the `graph_edges` lookup table. The `Edge.key_for_enrichment` property in [`mx/Edge.py`](https://github.com/hbmartin/graphviz2drawio/blob/main/mx/Edge.py) (lines 111‑116) generates a key based on the SVG text content:

```python
cleaned_label = "\n".join(
    [label.text.replace("\xa0", " ") for label in self.labels],
)
return f"{self.gid}-{cleaned_label}"

```

This enrichment key combines the edge's graph ID (`gid`) with the cleaned label text extracted from the SVG. The `convert` function then uses this key to retrieve the corresponding attribute dictionary from `graph_edges`, effectively linking the visual representation back to the original `xlabel` or `label` metadata. Because the lookup table was constructed with `xlabel` precedence, edges with distinct `xlabel` values correctly map to their specific attribute sets during this enrichment phase.

## Summary

- **`xlabel` takes precedence** over `label` when forming the lookup key in [`graphviz2drawio.py`](https://github.com/hbmartin/graphviz2drawio/blob/main/graphviz2drawio.py), ensuring edges with different `xlabel` values receive distinct attribute entries.
- **Visual labels originate from SVG** `<text>` elements parsed by `EdgeFactory.from_svg`, independent of the original Graphviz label attributes.
- **Enrichment relies on text-based keys** generated by `Edge.key_for_enrichment` to map SVG-derived labels back to the pygraphviz attribute dictionary.
- **Parallel edge merging** uses geometric keys (`key_for_label`) rather than label values, while attribute distinction relies on the `xlabel`/`label` lookup logic.

## Frequently Asked Questions

### Does xlabel override label in graphviz2drawio?

Yes, during the construction of the edge attribute lookup table in [`graphviz2drawio.py`](https://github.com/hbmartin/graphviz2drawio/blob/main/graphviz2drawio.py), the code explicitly checks for `xlabel` first using the expression `e.attr.get("xlabel") or e.attr.get("label")`. This ensures that when both attributes are present, the `xlabel` value determines the dictionary key used for attribute enrichment.

### Where does the visual edge text come from?

The visual text displayed on edges originates from SVG `<text>` elements extracted by the `EdgeFactory.from_svg` method in [`mx/EdgeFactory.py`](https://github.com/hbmartin/graphviz2drawio/blob/main/mx/EdgeFactory.py). This process parses the rendered SVG output to collect text objects, meaning the displayed content depends on what Graphviz rendered rather than the raw `label` or `xlabel` attribute values stored in the DOT file.

### How are parallel edges with different labels handled?

Parallel edges are merged during SVG parsing based on geometric properties using `Edge.key_for_label` in [`mx/Edge.py`](https://github.com/hbmartin/graphviz2drawio/blob/main/mx/Edge.py), which considers the edge's curve shape and direction rather than label content. However, the subsequent enrichment step uses `key_for_enrichment`—which incorporates the SVG text content—to distinguish edges with different `xlabel` or `label` values and apply the correct attributes from the lookup table.

### What is the purpose of the edge enrichment step?

The enrichment step in `graphviz2drawio.convert` maps pygraphviz edge attributes onto the SVG-derived edge objects by matching the `key_for_enrichment` (based on SVG text) against the lookup table built with `xlabel`/`label` keys. This restoration process ensures that styling, metadata, and other Graphviz properties survive the conversion to Draw.io format despite the intermediate SVG rendering step.