Skip to content

fix(parser): key style map by referenceable id only - #13

Merged
danielebarbaro merged 1 commit into
mainfrom
fix/placemark-and-style-extraction
Sep 8, 2026
Merged

danielebarbaro merged 1 commit into
mainfrom
fix/placemark-and-style-extraction

Conversation

@danielebarbaro

Copy link
Copy Markdown
Contributor

Problem

Anonymous styles overwrite each other

getStyles() runs //kml:Style and indexes every match by its id attribute:

$id = (string) $styleXml->attributes()->id;
// ...
$styles[$id] = $style;

That XPath also matches the <Style> elements declared inline inside a Placemark, which have no id. Every one of them casts to '', so they all land on the same key and silently overwrite each other. A document with ten inline styles produces one entry under '' holding whichever came last.

Inline styles cannot be referenced through a styleUrl in the first place, so having them in a map keyed by id serves no purpose.

Dead ->n fallbacks

'name' => (string) ($placemarkXml->name ?: $placemarkXml->n),

and the matching $document[0]->n branch in getDocumentName(). n is not a KML element; these look like the residue of a bad find/replace. Unreachable for any valid document.

Fix

  • Skip Style elements without an id in getStyles(), so the returned map contains only shared, referenceable styles.
  • Remove both ->n fallbacks.

Tests

tests/StyleAndNameExtractionTest.php, against a document with two shared styles and two anonymous inline ones:

  • regression test (fails on main): only the two id-bearing styles are returned, no '' key, and each keeps its own scale. On main this returns 3 entries, one of which is the clobbered '' bucket.
  • two guards confirming the name reading still works after dropping the ->n branches.

To be explicit about scope: the ->n removal is dead-code cleanup, not a live bug fix. The two name tests pass on main too; they are there so the removal is covered, not to demonstrate a defect.

Behaviour change

getStyles() no longer returns an entry under the '' key. Anything relying on that key was reading a single arbitrary inline style out of however many the document contained, so this is a correction rather than a loss of capability. Worth a note in the changelog.

Notes

Includes a one-line Pint fix in loadFromString() (\Exception -> Exception), since src/KmlParser.php fails pint --test on main and this PR touches the file.

getStyles() indexed every //kml:Style by its id attribute, including the
anonymous Style elements declared inline on a Placemark. Those have no
id, so they all collapsed onto the same empty string key and silently
overwrote each other; the map ended up holding whichever inline style
happened to come last. Inline styles cannot be reached through a
styleUrl anyway, so they are now skipped and the map contains only the
shared, referenceable styles.

Also drops the `?: $placemarkXml->n` and `$document[0]->n` fallbacks.
`n` is not a KML element and the branches were unreachable for any
valid document.
@danielebarbaro
danielebarbaro merged commit 8d7d4a6 into main Sep 8, 2026
18 of 19 checks passed
@danielebarbaro
danielebarbaro deleted the fix/placemark-and-style-extraction branch September 8, 2026 12:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant