crystal-lang / crystal

The Crystal Programming Language
https://crystal-lang.org
Apache License 2.0
19.36k stars 1.62k forks source link

XML serialization #10260

Open jkthorne opened 3 years ago

jkthorne commented 3 years ago

JSON and YAML have mappers and serializes it would be nice to have something for XML. I have been working with XML more lately and so this has become more apparent to me.

Blacksmoke16 commented 3 years ago

In the meantime you could always pipe it thru https://github.com/Blacksmoke16/oq, then leverage the JSON serializable stuff 😆.

Blacksmoke16 commented 3 years ago

As of https://github.com/Blacksmoke16/oq/releases/tag/v1.2.0, oq can now be used as a library:

require "oq"

# This could be any `IO`, e.g. an `HTTP` request body, etc.
input_io = IO::Memory.new %({"name":"Jim"})

# Create a processor, specifying that we want the output format to be `YAML`.
processor = OQ::Processor.new output_format: :yaml

File.open("./out.yml", "w") do |file|
  # Process the data using our custom input and output IOs.
  # The first argument represents the input arguments;
  # i.g. the filter and/or any other arguments that should be passed to `jq`.
  processor.process ["."], input: input_io, output: file
end
stakach commented 3 years ago

Thanks @Blacksmoke16 this came in handy for me - thought I'd share my code here for others that come looking

    require "oq"

    # Convert the XML to JSON for simple parsing
    # https://www.xml.com/pub/a/2006/05/31/converting-between-xml-and-json.html
    input_io = IO::Memory.new xml_string
    output_io = IO::Memory.new
    OQ::Converters::XML.deserialize input_io, output_io
    output_io.rewind

    # then can convert to JSON::Any
    JSON.parse(output_io)

    # or from_json
    MyClass.from_json output_io
Blacksmoke16 commented 3 years ago

@stakach Good to hear! IO.pipe might be helpful as well. E.g. you could call .deserialize with the writer, then use the reader for the .from_json call. If you spawn for each "step", you'll be able to concurrently deserialize the data into JSON while also deserializing the JSON into your obj.