Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adding support for XML parsing and shale type mapping #48

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

HassanAkbar
Copy link
Member

Adding support for XML parsing and Shale-type mapping.

Fixes #47

@HassanAkbar
Copy link
Member Author

@ronaldtse I've tried to make the structure for parsing XML as close to other structures as possible. is this correct or do we need to change something here?

@HassanAkbar HassanAkbar changed the title [WIP] adding support for XML parsing and shale type mapping adding support for XML parsing and shale type mapping Jan 30, 2024
@ronaldtse
Copy link
Contributor

@HassanAkbar actually this is not quite what I wanted. We need a way to allow users to "access XML element and attributes".

So the user should provide an XML schema, and also an XML document, like this, and allow the user to access elements:

@HassanAkbar
Copy link
Member Author

@ronaldtse I don't fully understand what you mean, But I will look into it and get back to you with questions related to this after some research.

@HassanAkbar
Copy link
Member Author

@ronaldtse I've looked at https://www.shalerb.org/#compiling-json-and-xml-schema, and figured how shale gem can generate ruby code from schemas provided in xml or json format.

From what I understand the flow is something like,

  • User provides an xml document. (this point is clear)
  • User provides the xml schema. (this is unclear, I have few questions related to this)
    • How will the user provide the schema? will he pass it as a string parameter or as a file or folder name?
    • Are we going to support both xml and json schemas or only xml schemas?
  • We will return the shale object for the given xml_document.

@ronaldtse
Copy link
Contributor

  • Are we going to support both xml and json schemas or only xml schemas?
  • We will return the shale object for the given xml_document.

The user will provide both:

  • XML document
  • XML schema that the document complies to

Steps:

  1. We pass the XML schema to Shale to obtain a Ruby object that can access the contents of the XML document.
  2. We pass the XML document to the step 1 Shale instance so we can access the content of the document.
  • How will the user provide the schema? will he pass it as a string parameter or as a file or folder name?

An XSD can be standalone (if it's complete), or it may include other XSDs via includes. So we have to take a file (if it's standalone) and also a folder (if it includes other files in the same folder).

  • Are we going to support both xml and json schemas or only xml schemas?

We want to support both, but let's finish XML first and do JSON next?

  • We will return the shale object for the given xml_document.

Yes.

hash[mapping.name] = content.strip
end
else
if object.class.attributes[mapping.attribute].collection?
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Convert if nested inside else to elsif.

serialize_to_hash(document)
end

def serialize_to_hash(object)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assignment Branch Condition size for serialize_to_hash is too high. [<11, 45, 16> 49.01/15]
Cyclomatic complexity for serialize_to_hash is too high. [13/6]
Method has too many lines. [25/10]
Perceived complexity for serialize_to_hash is too high. [16/7]

element
end

def get_content_value(content_mapping, element, only, except, delegates, instance)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid parameter lists longer than 5 parameters. [6/5]
Line is too long. [90/80]

mapper.send(content_mapping.method_to, instance, element,
doc, context)
else
mapper.send(content_mapping.method_to, instance, element, doc)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line is too long. [82/80]

# @return [::REXML::Document, ::Nokogiri::Document, ::Ox::Document]
#
# @api public
def as_xml(
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid parameter lists longer than 5 parameters. [8/5]

def load_schema(schema)
result = Shale::Schema.from_xml([schema])

result.values.each do |klass|
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use each_value instead of values.each.

klass = klass.gsub(/^require.*?\n/, "")
klass = klass.gsub(/< Shale::Mapper/, "< Lutaml::Xml::Mapper")

eval(klass, TOPLEVEL_BINDING)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of eval is a serious security risk.

def self.load_schema(schema, root_schema)
result = Shale::Schema.from_xml([schema])

result.values.each do |klass|
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use each_value instead of values.each.

"Address" => {
"City" => "London",
"ZIP" => "E1 6AN",
"content" => ["Oxford Street"]
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Put a comma after the last item of a multiline hash.


RSpec.describe Lutaml::Xml::LutamlPath::DocumentWrapper do
describe ".parse" do
subject(:lutaml_path) { described_class.new(Lutaml::Xml::Parsers::Xml.parse(xml_file_path)) }
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line is too long. [97/80]

if mapping == "content"
attribute_name = object.class.xml_mapping.content.attribute.to_s
hash[attribute_name] ||= []
hash[attribute_name] << content.strip unless content.strip&.empty?
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid calling empty? with the safe navigation operator in conditionals.

serialize_to_hash(document)
end

def serialize_to_hash(object)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assignment Branch Condition size for serialize_to_hash is too high. [<11, 45, 15> 48.69/15]
Cyclomatic complexity for serialize_to_hash is too high. [12/6]
Method has too many lines. [25/10]
Perceived complexity for serialize_to_hash is too high. [15/7]

@HassanAkbar
Copy link
Member Author

@ronaldtse I have updated this PR. Is this what you were looking for ?

result.values.each do |klass|
# Temporary solution will update in the parser
klass = klass.gsub(/^require.*?\n/, "")
klass = klass.gsub(/< Shale::Mapper/, "< Lutaml::Xml::Mapper")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to fork the gem

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ronaldtse Sure, I'll fork this and open a PR in that repo.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ronaldtse Should I fork the gem and move everything there or only update this part of the code in the forked gem and keep everything else here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ronaldtse Forked the gem at lutaml/shale -> https://github.com/lutaml/shale

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.

Plan adding support for XML parsing and Shale-type mapping.
2 participants