Skip to content

Conversation

@bukzor
Copy link
Contributor

@bukzor bukzor commented Nov 14, 2025

Summary

XML element order is now preserved when converting to JSON. Previously, keys were alphabetically sorted due to Go's map iteration order.

Problem

XML element order is semantically significant. For example:

  • CSV-like data where column order matters
  • Serialized objects where field order has meaning
  • Configuration files where order affects behavior

Previously, xq's JSON output lost this ordering information:

echo '<root><name>a</name><msg>b</msg><args>c</args></root>' | xq -j
# Before: {"root":{"args":"c","msg":"b","name":"a"}}  # alphabetical

Solution

Added OrderedMap type that preserves insertion order by implementing custom json.Marshaler:

echo '<root><name>a</name><msg>b</msg><args>c</args></root>' | xq -j
# After: {"root":{"name":"a","msg":"b","args":"c"}}  # document order

Changes

  • Added OrderedMap type with custom MarshalJSON() implementation
  • Updated NodeToJSON() to return *OrderedMap instead of map[string]interface{}
  • Updated nodeToJSONInternal() to use OrderedMap
  • Updated addToResult() to work with *OrderedMap
  • Added TestElementOrderInJSON to verify ordering is preserved
  • Updated TestCDATASupport to work with OrderedMap
  • Updated formatted3.json test fixture to match document order

Breaking Change

This is technically a breaking change for code that:

  • Uses type assertions to check for map[string]interface{}
  • Relies on alphabetical ordering of keys

However, the previous behavior was arguably a bug, and most code should work with the new OrderedMap type since it marshals to standard JSON.

🤖 Generated with Claude Code

XML element order is semantically significant and should be preserved
when converting to JSON. Previously, Go's map iteration caused keys to
be alphabetically sorted in the JSON output, losing the document order.

Changes:
- Added OrderedMap type that implements json.Marshaler
- Updated NodeToJSON to return OrderedMap instead of map[string]interface{}
- Updated nodeToJSONInternal to use OrderedMap
- Updated addToResult to work with OrderedMap
- Added TestElementOrderInJSON to verify ordering is preserved
- Updated TestCDATASupport to work with OrderedMap
- Updated formatted3.json test fixture to match element order

Example:
  Input: <root><name>a</name><msg>b</msg><args>c</args></root>
  Before: {"root":{"args":"c","msg":"b","name":"a"}} (alphabetical)
  After: {"root":{"name":"a","msg":"b","args":"c"}} (document order)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@codecov-commenter
Copy link

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 80.95238% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 80.83%. Comparing base (ec5a59a) to head (bc62ef3).

Files with missing lines Patch % Lines
internal/utils/jsonutil.go 80.95% 5 Missing and 3 partials ⚠️
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #167      +/-   ##
==========================================
+ Coverage   80.57%   80.83%   +0.25%     
==========================================
  Files           5        5              
  Lines         690      720      +30     
==========================================
+ Hits          556      582      +26     
- Misses         92       94       +2     
- Partials       42       44       +2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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.

2 participants