Skip to content

Commit

Permalink
updated import functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
suleman-uzair committed Nov 22, 2024
1 parent bce680f commit 35d0ccd
Show file tree
Hide file tree
Showing 8 changed files with 113 additions and 44 deletions.
2 changes: 2 additions & 0 deletions lib/lutaml/xsd/attribute.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ module Lutaml
module Xsd
class Attribute < Lutaml::Model::Serializable
attribute :use, :string
attribute :ref, :string
attribute :name, :string
attribute :type, :string
attribute :default, :string
Expand All @@ -15,6 +16,7 @@ class Attribute < Lutaml::Model::Serializable
namespace "http://www.w3.org/2001/XMLSchema", "xsd"

map_attribute :use, to: :use
map_attribute :ref, to: :ref
map_attribute :name, to: :name
map_attribute :type, to: :type
map_attribute :default, to: :default
Expand Down
32 changes: 0 additions & 32 deletions lib/lutaml/xsd/config.rb

This file was deleted.

51 changes: 51 additions & 0 deletions lib/lutaml/xsd/glob.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# frozen_string_literal: true

module Lutaml
module Xsd
module Glob
module_function

def set_path_or_url(location)
return nullify_path_and_url if location.nil?

@location = location
@url = location if location.start_with?(/http\w?:\/{2}[^.]+/)
@path = File.expand_path(location) unless @url
rescue => e
raise Error, "Invalid location: #{location}"
end

def location
@location
end

def path?
!@path.nil?
end

def url?
!@url.nil?
end

def location?
url? || path?
end

def schema_location_path(schema_location)
if schema_location.start_with?("/") || location.end_with?("/")
location + schema_location
else
location + "/" + schema_location
end
end

private

def nullify_location
@location = nil
@path = nil
@url = nil
end
end
end
end
17 changes: 17 additions & 0 deletions lib/lutaml/xsd/import.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# frozen_string_literal: true

require "net/http"
module Lutaml
module Xsd
class Import < Lutaml::Model::Serializable
Expand All @@ -14,6 +15,22 @@ class Import < Lutaml::Model::Serializable
map_attribute :id, to: :id
map_attribute :namespace, to: :namespace
end

def import_schema
if Glob.location? && schema_location
if Glob.url?
Net::HTTP.get(
URI.parse(
Glob.schema_location_path(schema_location),
),
)
else
File.read(
Glob.schema_location_path(schema_location),
)
end
end
end
end
end
end
49 changes: 40 additions & 9 deletions lib/lutaml/xsd/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ module Xsd
class Schema < Lutaml::Model::Serializable
attribute :xmlns, :string
attribute :import, Import, collection: true
attribute :schema, Schema, collection: true
attribute :schemas, Schema, collection: true
attribute :import_and_include, :hash, collection: true
attribute :include, Include, collection: true
attribute :element, Element, collection: true
attribute :complex_type, ComplexType, collection: true
Expand All @@ -22,7 +23,7 @@ class Schema < Lutaml::Model::Serializable
namespace "http://www.w3.org/2001/XMLSchema", "xsd"

map_attribute :xmlns, to: :xmlns, namespace: "http://csrc.nist.gov/ns/oscal/metaschema/1.0", prefix: nil
map_element :import, to: :import, with: { from: :from_schema, to: :to_schema }
map_element :import, to: :import, with: { from: :from_schema, to: :to_schema_xml }
map_element :include, to: :include
map_element :element, to: :element
map_element :complexType, to: :complex_type
Expand All @@ -35,16 +36,46 @@ class Schema < Lutaml::Model::Serializable
map_attribute :targetNamespace, to: :target_namespace
end

def self.processed_schemas
@processed_schemas ||= {}
end

def self.schema_processed?(id)
processed_schemas[id]
end

def self.schema_processed(id)
processed_schemas[id] = true
end

def from_schema(model, value)
# IN-PROGRESS
# value.each do |imported_schema|
# binding.irb
# imported_schema.from_schema(model, value)
# end
model.import_and_include += value
model.import_and_include&.flatten!&.uniq!
value.each do |imported_schema|
next if self.class.schema_processed?(imported_schema["id"])

self.class.schema_processed(imported_schema["id"])
imported_schema["schema_location"] = imported_schema.delete("__schema_location")&.dig(:schema_location)
schema_imported = Import.new(
id: imported_schema["id"],
namespace: imported_schema["namespace"],
schema_location: imported_schema["schema_location"],
).import_schema
model.schemas << Lutaml::Xsd.parse(schema_imported, location: Glob.location) if schema_imported
end
end

def to_schema(model, parent, doc)
# binding.irb
def to_schema_xml(model, parent, doc)
model.import_and_include.each_with_index do |imported_schema, index|
import_element = doc.create_element("import")
import_element.set_attribute("id", imported_schema["id"]) if imported_schema["id"]
import_element.set_attribute("namespace", imported_schema["namespace"]) if imported_schema["namespace"]
if imported_schema["__schema_location"]&.key?(:schema_location)
import_element.set_attribute("schemaLocation", imported_schema["__schema_location"][:schema_location])
end
model.import_and_include.delete_at(index)
parent.add_child(import_element)
end
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/lutaml/xsd/xsd.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class Error < StandardError; end
module_function

def parse(xsd, location: nil)
Config.set_path_or_url(location)
Glob.set_path_or_url(location)
Schema.from_xml(xsd)
end
end
Expand Down
2 changes: 1 addition & 1 deletion spec/lutaml/fixtures/omml_schema.xsd
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="qualified" blockDefault="#all" targetNamespace="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
<xsd:import id="w" namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main" schemaLocation="/master/wml.xsd" />
<xsd:import id="w" namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main" schemaLocation="/wml.xsd" />
<xsd:import id="xml" namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:simpleType name="ST_Integer255">
<xsd:annotation>
Expand Down
2 changes: 1 addition & 1 deletion spec/lutaml/xsd_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

RSpec.describe Lutaml::Xsd do
# TODO: remove dummy location url
subject(:parsed_schema) { described_class.parse(schema, location: "https://www.something.com/") }
subject(:parsed_schema) { described_class.parse(schema, location: "https://raw.githubusercontent.com/t-yuki/ooxml-xsd/refs/heads/master") }

it "has a version number" do
expect(Lutaml::Xsd::VERSION).not_to be nil
Expand Down

0 comments on commit 35d0ccd

Please sign in to comment.