From e2a4bf16d02744b1552eb9bfd56f10abccb36a7c Mon Sep 17 00:00:00 2001 From: Karol Date: Thu, 12 Oct 2023 22:50:35 +0200 Subject: [PATCH] add order to json, since json does not guarantee the order of inserted keys, but it is important for xml --- lib/dachsfisch/json2_xml_converter.rb | 6 +- lib/dachsfisch/xml2_json_converter.rb | 9 +- spec/support/examples.rb | 174 +++++++++++++++++--------- 3 files changed, 127 insertions(+), 62 deletions(-) diff --git a/lib/dachsfisch/json2_xml_converter.rb b/lib/dachsfisch/json2_xml_converter.rb index 51b9139..45a61a1 100644 --- a/lib/dachsfisch/json2_xml_converter.rb +++ b/lib/dachsfisch/json2_xml_converter.rb @@ -23,8 +23,8 @@ def execute def add_element(xml, element) return unless element.is_a? Hash - element.each do |key, value| - add_node(xml, key, value) unless key.start_with?('@') + element['@@order']&.each do |key| + add_node(xml, key, element[key]) unless key.start_with?('@') end end @@ -44,7 +44,7 @@ def add_node(xml, key, element) end def handle_attribute_and_namespaces(node, element) - element.keys.filter {|element_key| element_key.start_with?('@') }.each do |attribute_key| + element.keys.filter {|element_key| element_key.start_with?(/@[^@]/) }.each do |attribute_key| if attribute_key.start_with? '@xmlns' element[attribute_key].each do |namespace_key, namespace| # add namespace of current scope to node. The root-ns($) gets 'xmlns' as key, named namespaces 'xmlns:name' respectively. diff --git a/lib/dachsfisch/xml2_json_converter.rb b/lib/dachsfisch/xml2_json_converter.rb index 490f2e1..e3b4623 100644 --- a/lib/dachsfisch/xml2_json_converter.rb +++ b/lib/dachsfisch/xml2_json_converter.rb @@ -14,20 +14,27 @@ def execute @fragment.elements.deconstruct.each do |root| result[node_name(root)] = extract_node(root) end + add_order_to_hash result result.to_json end private + def add_order_to_hash(hash) + return if hash.keys.reject {|key| key.start_with?('@')}.empty? + + hash['@@order'] = hash.keys.reject {|key| key.start_with?('@') } + end + def extract_node(node) hash = {} active_namespaces = add_namespaces_to_active_namespaces(node) hash['@xmlns'] = active_namespaces unless active_namespaces.empty? - handle_attributes(hash, node) node.children.each do |child| handle_content(hash, child) end + add_order_to_hash hash hash end diff --git a/spec/support/examples.rb b/spec/support/examples.rb index 893389f..d6c0605 100644 --- a/spec/support/examples.rb +++ b/spec/support/examples.rb @@ -13,8 +13,10 @@ def self.json <<~JSON { "alice": { - "$1": "bob" - } + "$1": "bob", + "@@order": ["$1"] + }, + "@@order": ["alice"] } JSON end @@ -31,8 +33,10 @@ def self.json <<~JSON { "test": { - "$1": "test" - } + "$1": "test", + "@@order": ["$1"] + }, + "@@order": ["test"] } JSON end @@ -50,12 +54,16 @@ def self.json { "alice": { "bob": { - "$1": "charlie" + "$1": "charlie", + "@@order": ["$1"] }, "david": { - "$1": "edgar" - } - } + "$1": "edgar", + "@@order": ["$1"] + }, + "@@order": ["bob", "david"] + }, + "@@order": ["alice"] } JSON end @@ -77,13 +85,17 @@ def self.json "alice": { "bob": [ { - "$1": "charlie" + "$1": "charlie", + "@@order": ["$1"] }, { - "$1": "david" + "$1": "david", + "@@order": ["$1"] } - ] - } + ], + "@@order": ["bob"] + }, + "@@order": ["alice"] } JSON end @@ -104,8 +116,10 @@ def self.json { "alice": { "$1": "bob", - "@charlie": "david" - } + "@charlie": "david", + "@@order": ["$1"] + }, + "@@order": ["alice"] } JSON end @@ -125,8 +139,10 @@ def self.json "$1": "bob", "@xmlns": { "$": "http://some-namespace" - } - } + }, + "@@order": ["$1"] + }, + "@@order": ["alice"] } JSON end @@ -147,8 +163,10 @@ def self.json "@xmlns": { "$": "http://some-namespace", "charlie": "http://some-other-namespace" - } - } + }, + "@@order": ["$1"] + }, + "@@order": ["alice"] } JSON end @@ -170,12 +188,16 @@ def self.json "$": "http://some-namespace" }, "bob": { - "$1": "david" + "$1": "david", + "@@order": ["$1"] }, "charlie:edgar": { - "$1": "frank" - } - } + "$1": "frank", + "@@order": ["$1"] + }, + "@@order": ["bob", "charlie:edgar"] + }, + "@@order": ["alice"] } JSON end @@ -197,10 +219,13 @@ def self.json "alice": { "$1": "bob", "charlie": { - "$1": "bob2" + "$1": "bob2", + "@@order": ["$1"] }, - "$2": "bob3" - } + "$2": "bob3", + "@@order": ["$1", "charlie", "$2"] + }, + "@@order": ["alice"] } JSON end @@ -217,8 +242,10 @@ def self.json <<~JSON { "alice": { - "!1": "my comment" - } + "!1": "my comment", + "@@order": ["!1"] + }, + "@@order": ["alice"] } JSON end @@ -237,8 +264,10 @@ def self.json <<~JSON { "alice": { - "!1": " my comment " - } + "!1": " my comment ", + "@@order": ["!1"] + }, + "@@order": ["alice"] } JSON end @@ -259,16 +288,21 @@ def self.json "alice": { "bob": [ { - "$1": "charlie" + "$1": "charlie", + "@@order": ["$1"] }, { - "$1": "david" + "$1": "david", + "@@order": ["$1"] }, { - "$1": "edgar" + "$1": "edgar", + "@@order": ["$1"] } - ] - } + ], + "@@order": ["bob"] + }, + "@@order": ["alice"] } JSON end @@ -291,8 +325,10 @@ def self.json "alice": { "bob": { "@foo": "bar" - } - } + }, + "@@order": ["bob"] + }, + "@@order": ["alice"] } JSON end @@ -311,8 +347,10 @@ def self.json <<~JSON { "alice": { - "#1": "" - } + "#1": "", + "@@order": ["#1"] + }, + "@@order": ["alice"] } JSON end @@ -329,8 +367,10 @@ def self.json <<~JSON { "alice": { - "#1": "" - } + "#1": "", + "@@order": ["#1"] + }, + "@@order": ["alice"] } JSON end @@ -347,8 +387,10 @@ def self.json <<~JSON { "alice": { - "#1": " " - } + "#1": " ", + "@@order": ["#1"] + }, + "@@order": ["alice"] } JSON end @@ -366,9 +408,12 @@ def self.json { "alice": { "bob": { - "$1": "charlie" - } - } + "$1": "charlie", + "@@order": ["$1"] + }, + "@@order": ["bob"] + }, + "@@order": ["alice"] } JSON end @@ -393,8 +438,10 @@ def self.json <<~JSON { "alice": { - "$1": 1 - } + "$1": 1, + "@@order": ["$1"] + }, + "@@order": ["alice"] } JSON end @@ -418,9 +465,12 @@ def self.json "@xmlns": { "$": "http://some-other-namespace" }, - "$1": "charlie" - } - } + "$1": "charlie", + "@@order": ["$1"] + }, + "@@order": ["bob"] + }, + "@@order": ["alice"] } JSON end @@ -442,8 +492,10 @@ def self.json "@xmlns": { "bob": "http://some-other-namespace" }, - "$1": "charlie" - } + "$1": "charlie", + "@@order": ["$1"] + }, + "@@order": ["bob:alice"] } JSON end @@ -460,11 +512,14 @@ def self.json <<~JSON { "alice": { - "$1": "bob" + "$1": "bob", + "@@order": ["$1"] }, "charlie": { - "$1": "david" - } + "$1": "david", + "@@order": ["$1"] + }, + "@@order": ["alice", "charlie"] } JSON end @@ -485,14 +540,17 @@ def self.json "@xmlns": { "bob": "http://some-namespace" }, - "$1": "charlie" + "$1": "charlie", + "@@order": ["$1"] }, "david:edgar": { "@xmlns": { "david": "http://some-other-namespace" }, - "$1": "foobar" - } + "$1": "foobar", + "@@order": ["$1"] + }, + "@@order": ["bob:alice", "david:edgar"] } JSON end