diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 7779003..833b59b 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -2,6 +2,11 @@
# See https://github.com/metanorma/cimas
name: release
+permissions:
+ contents: write
+ packages: write
+ id-token: write
+
on:
workflow_dispatch:
inputs:
@@ -16,10 +21,8 @@ on:
jobs:
release:
- uses: metanorma/ci/.github/workflows/rubygems-release.yml@main
+ uses: relaton/support/.github/workflows/release.yml@main
with:
next_version: ${{ github.event.inputs.next_version }}
secrets:
- rubygems-api-key: ${{ secrets.METANORMA_CI_RUBYGEMS_API_KEY }}
- pat_token: ${{ secrets.METANORMA_CI_PAT_TOKEN }}
-
+ rubygems-api-key: ${{ secrets.LUTAML_CI_RUBYGEMS_API_KEY }}
diff --git a/.rubocop.yml b/.rubocop.yml
index 762eebb..7ee1ffb 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -1,8 +1,19 @@
-AllCops:
- TargetRubyVersion: 3.0
+# Auto-generated by Cimas: Do not edit it manually!
+# See https://github.com/metanorma/cimas
+inherit_from:
+ - https://raw.githubusercontent.com/riboseinc/oss-guides/main/ci/rubocop.yml
+ - .rubocop_todo.yml
+
+inherit_mode:
+ merge:
+ - Exclude
-Style/StringLiterals:
- EnforcedStyle: double_quotes
+# local repo-specific modifications
+# ...
+plugins:
+ - rubocop-rspec
+ - rubocop-performance
+ - rubocop-rake
-Style/StringLiteralsInInterpolation:
- EnforcedStyle: double_quotes
+AllCops:
+ TargetRubyVersion: 3.0
diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml
new file mode 100644
index 0000000..3189721
--- /dev/null
+++ b/.rubocop_todo.yml
@@ -0,0 +1,241 @@
+# This configuration was generated by
+# `rubocop --auto-gen-config`
+# on 2026-04-01 07:11:02 UTC using RuboCop version 1.86.0.
+# The point is for the user to remove these configuration records
+# one by one as the offenses are removed from the code base.
+# Note that changes in the inspected code, or installation of new
+# versions of RuboCop, may require this file to be generated again.
+
+# Offense count: 17
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: TreatCommentsAsGroupSeparators, ConsiderPunctuation.
+Bundler/OrderedGems:
+ Exclude:
+ - 'Gemfile'
+
+# Offense count: 1
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: TreatCommentsAsGroupSeparators, ConsiderPunctuation.
+Gemspec/OrderedDependencies:
+ Exclude:
+ - 'reqif.gemspec'
+
+# Offense count: 1
+# This cop supports safe autocorrection (--autocorrect).
+Gemspec/RequireMFA:
+ Exclude:
+ - 'reqif.gemspec'
+
+# Offense count: 63
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle, IndentationWidth.
+# SupportedStyles: with_first_argument, with_fixed_indentation
+Layout/ArgumentAlignment:
+ Exclude:
+ - 'lib/reqif.rb'
+ - 'lib/reqif/datatypes.rb'
+ - 'lib/reqif/default_value.rb'
+ - 'lib/reqif/definition.rb'
+ - 'lib/reqif/doors/readonly_attributes.rb'
+ - 'lib/reqif/editable_atts.rb'
+ - 'lib/reqif/reqif_float.rb'
+ - 'lib/reqif/spec_attributes.rb'
+ - 'lib/reqif/type.rb'
+ - 'lib/reqif/values.rb'
+
+# Offense count: 2
+# This cop supports safe autocorrection (--autocorrect).
+Layout/ClosingParenthesisIndentation:
+ Exclude:
+ - 'spec/reqif/polarion_export_spec.rb'
+ - 'spec/spec_helper.rb'
+
+# Offense count: 22
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: AllowForAlignment.
+Layout/CommentIndentation:
+ Exclude:
+ - 'lib/reqif/doors/module_definition.rb'
+ - 'lib/reqif/doors/readonly_attributes.rb'
+ - 'lib/reqif/doors/rif_definition.rb'
+ - 'lib/reqif/req_if_tool_extension.rb'
+
+# Offense count: 1
+# This cop supports safe autocorrection (--autocorrect).
+Layout/ElseAlignment:
+ Exclude:
+ - 'spec/spec_helper.rb'
+
+# Offense count: 1
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: empty_lines, empty_lines_except_namespace, empty_lines_special, no_empty_lines, beginning_only, ending_only
+Layout/EmptyLinesAroundClassBody:
+ Exclude:
+ - 'lib/reqif/req_if_tool_extension.rb'
+
+# Offense count: 2
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle, IndentationWidth.
+# SupportedStyles: consistent, consistent_relative_to_receiver, special_for_inner_method_call, special_for_inner_method_call_in_parentheses
+Layout/FirstArgumentIndentation:
+ Exclude:
+ - 'spec/reqif/polarion_export_spec.rb'
+ - 'spec/spec_helper.rb'
+
+# Offense count: 4
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: normal, indented_internal_methods
+Layout/IndentationConsistency:
+ Exclude:
+ - 'lib/reqif/doors/readonly_attributes.rb'
+ - 'reqif.gemspec'
+
+# Offense count: 10
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: Width, EnforcedStyleAlignWith, AllowedPatterns.
+# SupportedStylesAlignWith: start_of_line, relative_to_receiver
+Layout/IndentationWidth:
+ Exclude:
+ - 'lib/reqif/doors/readonly_attributes.rb'
+ - 'spec/spec_helper.rb'
+
+# Offense count: 78
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: Max, AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, AllowRBSInlineAnnotation, AllowCopDirectives, AllowedPatterns, SplitStrings.
+# URISchemes: http, https
+Layout/LineLength:
+ Enabled: false
+
+# Offense count: 1
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: symmetrical, new_line, same_line
+Layout/MultilineMethodCallBraceLayout:
+ Exclude:
+ - 'spec/reqif/polarion_export_spec.rb'
+
+# Offense count: 1
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle, IndentationWidth.
+# SupportedStyles: aligned, indented
+Layout/MultilineOperationIndentation:
+ Exclude:
+ - 'spec/reqif_spec.rb'
+
+# Offense count: 8
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: final_newline, final_blank_line
+Layout/TrailingEmptyLines:
+ Exclude:
+ - 'lib/reqif/doors/identifier.rb'
+ - 'lib/reqif/doors/module_definition.rb'
+ - 'lib/reqif/doors/namespace.rb'
+ - 'lib/reqif/doors/readonly_attributes.rb'
+ - 'lib/reqif/doors/rif_definition.rb'
+ - 'lib/reqif/doors/string_type.rb'
+ - 'lib/reqif/string_type.rb'
+ - 'lib/reqif/xhtml/namespace.rb'
+
+# Offense count: 63
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: AllowInHeredoc.
+Layout/TrailingWhitespace:
+ Exclude:
+ - 'lib/reqif.rb'
+ - 'lib/reqif/datatypes.rb'
+ - 'lib/reqif/default_value.rb'
+ - 'lib/reqif/definition.rb'
+ - 'lib/reqif/doors/readonly_attributes.rb'
+ - 'lib/reqif/editable_atts.rb'
+ - 'lib/reqif/reqif_float.rb'
+ - 'lib/reqif/spec_attributes.rb'
+ - 'lib/reqif/type.rb'
+ - 'lib/reqif/values.rb'
+
+# Offense count: 1
+# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns, inherit_mode.
+# AllowedMethods: refine
+Metrics/BlockLength:
+ Max: 90
+
+# Offense count: 1
+# Configuration parameters: AllowedMethods, AllowedPatterns, Max.
+Metrics/CyclomaticComplexity:
+ Exclude:
+ - 'lib/reqif/reqif_float.rb'
+
+# Offense count: 3
+# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
+Metrics/MethodLength:
+ Max: 12
+
+# Offense count: 1
+# Configuration parameters: IgnoredMetadata.
+RSpec/DescribeClass:
+ Exclude:
+ - 'spec/reqif/polarion_export_spec.rb'
+
+# Offense count: 4
+# Configuration parameters: CountAsOne.
+RSpec/ExampleLength:
+ Max: 11
+
+# Offense count: 11
+RSpec/MultipleExpectations:
+ Max: 8
+
+# Offense count: 1
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: not_to, to_not
+RSpec/NotToNot:
+ Exclude:
+ - 'spec/reqif/polarion_export_spec.rb'
+
+# Offense count: 2
+# Configuration parameters: CustomTransform, IgnoreMethods, IgnoreMetadata, InflectorPath, EnforcedInflector.
+# SupportedInflectors: default, active_support
+RSpec/SpecFilePathFormat:
+ Exclude:
+ - 'spec/reqif/data_types_spec.rb'
+ - 'spec/reqif/tool_extension_spec.rb'
+
+# Offense count: 2
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: separated, grouped
+Style/AccessorGrouping:
+ Exclude:
+ - 'lib/reqif/high_precision_date_time.rb'
+
+# Offense count: 1
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: AllowIfModifier.
+Style/IfInsideElse:
+ Exclude:
+ - 'spec/spec_helper.rb'
+
+# Offense count: 1
+# This cop supports safe autocorrection (--autocorrect).
+Style/MultilineIfModifier:
+ Exclude:
+ - 'lib/reqif/reqif_float.rb'
+
+# Offense count: 2
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle, ConsistentQuotesInMultiline.
+# SupportedStyles: single_quotes, double_quotes
+Style/StringLiterals:
+ Exclude:
+ - 'reqif.gemspec'
+
+# Offense count: 1
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyleForMultiline.
+# SupportedStylesForMultiline: comma, consistent_comma, diff_comma, no_comma
+Style/TrailingCommaInArguments:
+ Exclude:
+ - 'spec/reqif/req_if_spec.rb'
diff --git a/CLAUDE.md b/CLAUDE.md
new file mode 100644
index 0000000..03c4d13
--- /dev/null
+++ b/CLAUDE.md
@@ -0,0 +1,73 @@
+# CLAUDE.md
+
+This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
+
+## Overview
+
+This is a Ruby gem (`reqif`) that parses and generates ReqIF (Requirements Interchange Format) XML documents. ReqIF is an OMG standard (v1.2) for exchanging requirements between different tools. The gem is part of the `lutaml` family.
+
+## Commands
+
+```bash
+bundle install # Install dependencies
+bundle exec rake # Run specs + rubocop (default)
+bundle exec rake spec # Run specs only
+bundle exec rake rubocop # Run linter only
+bundle exec rspec spec/reqif_spec.rb # Run a single spec file
+bundle exec bin/console # Start an IRB console with the gem loaded
+```
+
+## Architecture
+
+### Framework: lutaml/model
+
+All model classes inherit from `Lutaml::Model::Serializable` and use an `xml` DSL block to define XML serialization. The gem uses `Lutaml::Model::XmlAdapter::NokogiriAdapter` for XML parsing/generation.
+
+### Class-per-file pattern
+
+Each ReqIF concept is a separate class in `lib/reqif/`. Classes follow a consistent structure:
+
+```ruby
+module Reqif
+ class Foo < Lutaml::Model::Serializable
+ attribute :bar, :string
+ attribute :baz, SomeOtherClass
+
+ xml do
+ element "FOO"
+ namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ map_attribute "BAR", to: :bar
+ map_element "BAZ", to: :baz
+ end
+ end
+end
+```
+
+### Key model classes
+
+- `ReqIf` — Root element, contains `THE-HEADER`, `CORE-CONTENT`, `TOOL-EXTENSIONS`
+- `ReqIfContent` — Contains `DATATYPES`, `SPEC-TYPES`, `SPEC-OBJECTS`, `SPEC-RELATIONS`, `SPECIFICATIONS`, `SPEC-RELATION-GROUPS`
+- `SpecObject` — A single requirement with attributes (identifier, long_name, desc, etc.) and `VALUES`
+- `Specification` — A container/hierarchy that has `CHILDREN` referencing other specs
+- `SpecRelation` — A relation between two specs with `SOURCE` and `TARGET` references
+- `Values` — Container for `AttributeValue` elements (boolean, date, enumeration, integer, real, string, xhtml)
+- `Type` / `SpecObjectType` / `SpecificationType` — Type definitions for spec objects/specifications
+- `Datatypes` — Container for datatype definitions (boolean, date, enumeration, integer, real, string, xhtml)
+
+### Attribute naming conventions
+
+XML element names use uppercase-kebab-case (e.g., `SPEC-OBJECT`, `LAST-CHANGE`) while Ruby attributes use snake_case (e.g., `spec_object`, `last_change`). The `map_element` and `map_attribute` DSL methods handle the translation.
+
+### Autoloading
+
+Zeitwerk is used for autoloading. `lib/reqif.rb` sets up the loader and eager loads all classes.
+
+### XML round-trip testing
+
+Round-trip tests in `spec/reqif_spec.rb` parse fixture XML files, regenerate XML via `to_xml`, and compare canonicalization using `xml-c14n`. All fixture files under `spec/fixtures/` (`.xml`, `.reqif`) are automatically included.
+
+### Style
+
+- String literals: double quotes enforced by RuboCop
+- Ruby version: 3.0+
+- Frozen string literals: required at the top of every file
diff --git a/Gemfile b/Gemfile
index fbb8f2c..25c379a 100644
--- a/Gemfile
+++ b/Gemfile
@@ -5,9 +5,12 @@ source "https://rubygems.org"
# Specify your gem's dependencies in reqif.gemspec
gemspec
+gem "canon"
+gem "lutaml-model", github: "lutaml/lutaml-model", branch: "main"
+gem "nokogiri"
gem "rake", "~> 13.0"
gem "rspec", "~> 3.0"
gem "rubocop", "~> 1.21"
-gem "nokogiri"
gem "rubocop-performance"
-gem "xml-c14n"
+gem "rubocop-rake"
+gem "rubocop-rspec"
diff --git a/lib/reqif.rb b/lib/reqif.rb
index ecb43b2..7f33cc0 100644
--- a/lib/reqif.rb
+++ b/lib/reqif.rb
@@ -2,21 +2,77 @@
require "lutaml/model"
-Lutaml::Model::Config.configure do |config|
- require "lutaml/model/xml_adapter/nokogiri_adapter"
- config.xml_adapter = Lutaml::Model::XmlAdapter::NokogiriAdapter
-end
-
module Reqif
class Error < StandardError; end
- # Your code goes here...
+ autoload :AlternativeId, "reqif/alternative_id.rb"
+ autoload :AttributeDefinitionBoolean, "reqif/attribute_definition_boolean.rb"
+ autoload :AttributeDefinitionDate, "reqif/attribute_definition_date.rb"
+ autoload :AttributeDefinitionEnumeration,
+ "reqif/attribute_definition_enumeration.rb"
+ autoload :AttributeDefinitionInteger, "reqif/attribute_definition_integer.rb"
+ autoload :AttributeDefinitionReal, "reqif/attribute_definition_real.rb"
+ autoload :AttributeDefinitionString, "reqif/attribute_definition_string.rb"
+ autoload :AttributeDefinitionXhtml, "reqif/attribute_definition_xhtml.rb"
+ autoload :AttributeValueBoolean, "reqif/attribute_value_boolean.rb"
+ autoload :AttributeValueDate, "reqif/attribute_value_date.rb"
+ autoload :AttributeValueEnumeration, "reqif/attribute_value_enumeration.rb"
+ autoload :AttributeValueInteger, "reqif/attribute_value_integer.rb"
+ autoload :AttributeValueReal, "reqif/attribute_value_real.rb"
+ autoload :AttributeValueString, "reqif/attribute_value_string.rb"
+ autoload :AttributeValueXhtml, "reqif/attribute_value_xhtml.rb"
+ autoload :Children, "reqif/children.rb"
+ autoload :CoreContent, "reqif/core_content.rb"
+ autoload :DatatypeDefinitionBoolean, "reqif/datatype_definition_boolean.rb"
+ autoload :DatatypeDefinitionDate, "reqif/datatype_definition_date.rb"
+ autoload :DatatypeDefinitionEnumeration,
+ "reqif/datatype_definition_enumeration.rb"
+ autoload :DatatypeDefinitionInteger, "reqif/datatype_definition_integer.rb"
+ autoload :DatatypeDefinitionReal, "reqif/datatype_definition_real.rb"
+ autoload :DatatypeDefinitionString, "reqif/datatype_definition_string.rb"
+ autoload :DatatypeDefinitionXhtml, "reqif/datatype_definition_xhtml.rb"
+ autoload :Datatypes, "reqif/datatypes.rb"
+ autoload :DefaultValue, "reqif/default_value.rb"
+ autoload :Definition, "reqif/definition.rb"
+ autoload :Doors, "reqif/doors.rb"
+ autoload :EditableAtts, "reqif/editable_atts.rb"
+ autoload :EmbeddedValue, "reqif/embedded_value.rb"
+ autoload :EnumValue, "reqif/enum_value.rb"
+ autoload :HighPrecisionDateTime, "reqif/high_precision_date_time.rb"
+ autoload :Namespace, "reqif/namespace.rb"
+ autoload :Object, "reqif/object.rb"
+ autoload :Properties, "reqif/properties.rb"
+ autoload :RelationGroup, "reqif/relation_group.rb"
+ autoload :RelationGroupType, "reqif/relation_group_type.rb"
+ autoload :ReqIf, "reqif/req_if.rb"
+ autoload :ReqIfContent, "reqif/req_if_content.rb"
+ autoload :ReqIfHeader, "reqif/req_if_header.rb"
+ autoload :ReqIfToolExtension, "reqif/req_if_tool_extension.rb"
+ autoload :ReqifFloat, "reqif/reqif_float.rb"
+ autoload :ReqifInteger, "reqif/reqif_integer.rb"
+ autoload :Source, "reqif/source.rb"
+ autoload :SourceSpecification, "reqif/source_specification.rb"
+ autoload :SpecAttributes, "reqif/spec_attributes.rb"
+ autoload :SpecHierarchy, "reqif/spec_hierarchy.rb"
+ autoload :SpecObject, "reqif/spec_object.rb"
+ autoload :SpecObjectType, "reqif/spec_object_type.rb"
+ autoload :SpecObjects, "reqif/spec_objects.rb"
+ autoload :SpecRelation, "reqif/spec_relation.rb"
+ autoload :SpecRelationGroups, "reqif/spec_relation_groups.rb"
+ autoload :SpecRelationType, "reqif/spec_relation_type.rb"
+ autoload :SpecRelations, "reqif/spec_relations.rb"
+ autoload :SpecTypes, "reqif/spec_types.rb"
+ autoload :Specification, "reqif/specification.rb"
+ autoload :SpecificationType, "reqif/specification_type.rb"
+ autoload :Specifications, "reqif/specifications.rb"
+ autoload :SpecifiedValues, "reqif/specified_values.rb"
+ autoload :StringType, "reqif/string_type.rb"
+ autoload :Target, "reqif/target.rb"
+ autoload :TargetSpecification, "reqif/target_specification.rb"
+ autoload :TheHeader, "reqif/the_header.rb"
+ autoload :ToolExtensions, "reqif/tool_extensions.rb"
+ autoload :Type, "reqif/type.rb"
+ autoload :Values, "reqif/values.rb"
+ autoload :Xhtml, "reqif/xhtml.rb"
+ autoload :XhtmlContent, "reqif/xhtml_content.rb"
end
-
-require "zeitwerk"
-
-loader = Zeitwerk::Loader.for_gem
-loader.push_dir(__dir__) #, namespace: Reqif)
-loader.ignore("#{__dir__}/reqif.rb")
-loader.setup
-loader.eager_load
diff --git a/lib/reqif/alternative_id.rb b/lib/reqif/alternative_id.rb
index 50b41c5..50440ea 100644
--- a/lib/reqif/alternative_id.rb
+++ b/lib/reqif/alternative_id.rb
@@ -5,8 +5,8 @@ class AlternativeId < Lutaml::Model::Serializable
attribute :identifier, :string
xml do
- root "ALTERNATIVE-ID"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "ALTERNATIVE-ID"
+ namespace Namespace
map_attribute "IDENTIFIER", to: :identifier
end
diff --git a/lib/reqif/attribute_definition_boolean.rb b/lib/reqif/attribute_definition_boolean.rb
index 26c5842..be28209 100644
--- a/lib/reqif/attribute_definition_boolean.rb
+++ b/lib/reqif/attribute_definition_boolean.rb
@@ -12,10 +12,11 @@ class AttributeDefinitionBoolean < Lutaml::Model::Serializable
attribute :type, Type
xml do
- root "ATTRIBUTE-DEFINITION-BOOLEAN"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "ATTRIBUTE-DEFINITION-BOOLEAN"
+ namespace Namespace
+ ordered
- map_attribute "DESC", to: :desc
+ map_attribute "DESC", to: :desc, render_empty: true
map_attribute "IDENTIFIER", to: :identifier
map_attribute "IS-EDITABLE", to: :is_editable
map_attribute "LAST-CHANGE", to: :last_change
diff --git a/lib/reqif/attribute_definition_date.rb b/lib/reqif/attribute_definition_date.rb
index 1b69393..c14c3dc 100644
--- a/lib/reqif/attribute_definition_date.rb
+++ b/lib/reqif/attribute_definition_date.rb
@@ -12,10 +12,11 @@ class AttributeDefinitionDate < Lutaml::Model::Serializable
attribute :type, Type
xml do
- root "ATTRIBUTE-DEFINITION-DATE"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "ATTRIBUTE-DEFINITION-DATE"
+ namespace Namespace
+ ordered
- map_attribute "DESC", to: :desc
+ map_attribute "DESC", to: :desc, render_empty: true
map_attribute "IDENTIFIER", to: :identifier
map_attribute "IS-EDITABLE", to: :is_editable
map_attribute "LAST-CHANGE", to: :last_change
diff --git a/lib/reqif/attribute_definition_enumeration.rb b/lib/reqif/attribute_definition_enumeration.rb
index 6b8441d..087bf4b 100644
--- a/lib/reqif/attribute_definition_enumeration.rb
+++ b/lib/reqif/attribute_definition_enumeration.rb
@@ -13,10 +13,11 @@ class AttributeDefinitionEnumeration < Lutaml::Model::Serializable
attribute :type, Type
xml do
- root "ATTRIBUTE-DEFINITION-ENUMERATION"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "ATTRIBUTE-DEFINITION-ENUMERATION"
+ namespace Namespace
+ ordered
- map_attribute "DESC", to: :desc
+ map_attribute "DESC", to: :desc, render_empty: true
map_attribute "IDENTIFIER", to: :identifier
map_attribute "IS-EDITABLE", to: :is_editable
map_attribute "LAST-CHANGE", to: :last_change
diff --git a/lib/reqif/attribute_definition_integer.rb b/lib/reqif/attribute_definition_integer.rb
index 4d48787..5b3daaa 100644
--- a/lib/reqif/attribute_definition_integer.rb
+++ b/lib/reqif/attribute_definition_integer.rb
@@ -12,10 +12,11 @@ class AttributeDefinitionInteger < Lutaml::Model::Serializable
attribute :type, Type
xml do
- root "ATTRIBUTE-DEFINITION-INTEGER"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "ATTRIBUTE-DEFINITION-INTEGER"
+ namespace Namespace
+ ordered
- map_attribute "DESC", to: :desc
+ map_attribute "DESC", to: :desc, render_empty: true
map_attribute "IDENTIFIER", to: :identifier
map_attribute "IS-EDITABLE", to: :is_editable
map_attribute "LAST-CHANGE", to: :last_change
diff --git a/lib/reqif/attribute_definition_real.rb b/lib/reqif/attribute_definition_real.rb
index 28f3b0d..fb5a932 100644
--- a/lib/reqif/attribute_definition_real.rb
+++ b/lib/reqif/attribute_definition_real.rb
@@ -12,10 +12,11 @@ class AttributeDefinitionReal < Lutaml::Model::Serializable
attribute :type, Type
xml do
- root "ATTRIBUTE-DEFINITION-REAL"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "ATTRIBUTE-DEFINITION-REAL"
+ namespace Namespace
+ ordered
- map_attribute "DESC", to: :desc
+ map_attribute "DESC", to: :desc, render_empty: true
map_attribute "IDENTIFIER", to: :identifier
map_attribute "IS-EDITABLE", to: :is_editable
map_attribute "LAST-CHANGE", to: :last_change
diff --git a/lib/reqif/attribute_definition_string.rb b/lib/reqif/attribute_definition_string.rb
index 96db4ec..976b918 100644
--- a/lib/reqif/attribute_definition_string.rb
+++ b/lib/reqif/attribute_definition_string.rb
@@ -12,10 +12,11 @@ class AttributeDefinitionString < Lutaml::Model::Serializable
attribute :type, Type
xml do
- root "ATTRIBUTE-DEFINITION-STRING"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "ATTRIBUTE-DEFINITION-STRING"
+ namespace Namespace
+ ordered
- map_attribute "DESC", to: :desc
+ map_attribute "DESC", to: :desc, render_empty: true
map_attribute "IDENTIFIER", to: :identifier
map_attribute "IS-EDITABLE", to: :is_editable
map_attribute "LAST-CHANGE", to: :last_change
diff --git a/lib/reqif/attribute_definition_xhtml.rb b/lib/reqif/attribute_definition_xhtml.rb
index 2b79a53..47b53fe 100644
--- a/lib/reqif/attribute_definition_xhtml.rb
+++ b/lib/reqif/attribute_definition_xhtml.rb
@@ -12,10 +12,11 @@ class AttributeDefinitionXhtml < Lutaml::Model::Serializable
attribute :type, Type
xml do
- root "ATTRIBUTE-DEFINITION-XHTML"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "ATTRIBUTE-DEFINITION-XHTML"
+ namespace Namespace
+ ordered
- map_attribute "DESC", to: :desc
+ map_attribute "DESC", to: :desc, render_empty: true
map_attribute "IDENTIFIER", to: :identifier
map_attribute "IS-EDITABLE", to: :is_editable
map_attribute "LAST-CHANGE", to: :last_change
diff --git a/lib/reqif/attribute_value_boolean.rb b/lib/reqif/attribute_value_boolean.rb
index f78bdb5..2ad49c7 100644
--- a/lib/reqif/attribute_value_boolean.rb
+++ b/lib/reqif/attribute_value_boolean.rb
@@ -6,8 +6,9 @@ class AttributeValueBoolean < Lutaml::Model::Serializable
attribute :definition, Definition
xml do
- root "ATTRIBUTE-VALUE-BOOLEAN"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "ATTRIBUTE-VALUE-BOOLEAN"
+ namespace Namespace
+ ordered
map_attribute "THE-VALUE", to: :the_value
map_element "DEFINITION", to: :definition
diff --git a/lib/reqif/attribute_value_date.rb b/lib/reqif/attribute_value_date.rb
index dee0f98..312694b 100644
--- a/lib/reqif/attribute_value_date.rb
+++ b/lib/reqif/attribute_value_date.rb
@@ -2,12 +2,13 @@
module Reqif
class AttributeValueDate < Lutaml::Model::Serializable
- attribute :the_value, :date_time
+ attribute :the_value, HighPrecisionDateTime
attribute :definition, Definition
xml do
- root "ATTRIBUTE-VALUE-DATE"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "ATTRIBUTE-VALUE-DATE"
+ namespace Namespace
+ ordered
map_attribute "THE-VALUE", to: :the_value
map_element "DEFINITION", to: :definition
diff --git a/lib/reqif/attribute_value_enumeration.rb b/lib/reqif/attribute_value_enumeration.rb
index a8ed824..fa7f0cd 100644
--- a/lib/reqif/attribute_value_enumeration.rb
+++ b/lib/reqif/attribute_value_enumeration.rb
@@ -6,8 +6,9 @@ class AttributeValueEnumeration < Lutaml::Model::Serializable
attribute :values, Values
xml do
- root "ATTRIBUTE-VALUE-ENUMERATION"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "ATTRIBUTE-VALUE-ENUMERATION"
+ namespace Namespace
+ ordered
map_element "DEFINITION", to: :definition
map_element "VALUES", to: :values
diff --git a/lib/reqif/attribute_value_integer.rb b/lib/reqif/attribute_value_integer.rb
index fb285bf..889e3f4 100644
--- a/lib/reqif/attribute_value_integer.rb
+++ b/lib/reqif/attribute_value_integer.rb
@@ -2,12 +2,13 @@
module Reqif
class AttributeValueInteger < Lutaml::Model::Serializable
- attribute :the_value, :integer
+ attribute :the_value, ReqifInteger
attribute :definition, Definition
xml do
- root "ATTRIBUTE-VALUE-INTEGER"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "ATTRIBUTE-VALUE-INTEGER"
+ namespace Namespace
+ ordered
map_attribute "THE-VALUE", to: :the_value
map_element "DEFINITION", to: :definition
diff --git a/lib/reqif/attribute_value_real.rb b/lib/reqif/attribute_value_real.rb
index cf52627..8425a04 100644
--- a/lib/reqif/attribute_value_real.rb
+++ b/lib/reqif/attribute_value_real.rb
@@ -2,12 +2,13 @@
module Reqif
class AttributeValueReal < Lutaml::Model::Serializable
- attribute :the_value, :float
+ attribute :the_value, ReqifFloat
attribute :definition, Definition
xml do
- root "ATTRIBUTE-VALUE-REAL"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "ATTRIBUTE-VALUE-REAL"
+ namespace Namespace
+ ordered
map_attribute "THE-VALUE", to: :the_value
map_element "DEFINITION", to: :definition
diff --git a/lib/reqif/attribute_value_string.rb b/lib/reqif/attribute_value_string.rb
index fe586ac..d45ce8e 100644
--- a/lib/reqif/attribute_value_string.rb
+++ b/lib/reqif/attribute_value_string.rb
@@ -6,8 +6,9 @@ class AttributeValueString < Lutaml::Model::Serializable
attribute :definition, Definition
xml do
- root "ATTRIBUTE-VALUE-STRING"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "ATTRIBUTE-VALUE-STRING"
+ namespace Namespace
+ ordered
map_attribute "THE-VALUE", to: :the_value
map_element "DEFINITION", to: :definition
diff --git a/lib/reqif/attribute_value_xhtml.rb b/lib/reqif/attribute_value_xhtml.rb
index 8100179..1572c0f 100644
--- a/lib/reqif/attribute_value_xhtml.rb
+++ b/lib/reqif/attribute_value_xhtml.rb
@@ -8,8 +8,9 @@ class AttributeValueXhtml < Lutaml::Model::Serializable
attribute :definition, Definition
xml do
- root "ATTRIBUTE-VALUE-XHTML"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "ATTRIBUTE-VALUE-XHTML"
+ namespace Namespace
+ ordered
map_attribute "IS-SIMPLIFIED", to: :is_simplified
map_element "THE-VALUE", to: :the_value
diff --git a/lib/reqif/children.rb b/lib/reqif/children.rb
index eb442fb..5de4f60 100644
--- a/lib/reqif/children.rb
+++ b/lib/reqif/children.rb
@@ -5,8 +5,9 @@ class Children < Lutaml::Model::Serializable
attribute :spec_hierarchy, SpecHierarchy, collection: true
xml do
- root "CHILDREN"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "CHILDREN"
+ namespace Namespace
+ ordered
map_element "SPEC-HIERARCHY", to: :spec_hierarchy
end
diff --git a/lib/reqif/core_content.rb b/lib/reqif/core_content.rb
index 7f2819e..e97ced5 100644
--- a/lib/reqif/core_content.rb
+++ b/lib/reqif/core_content.rb
@@ -5,8 +5,9 @@ class CoreContent < Lutaml::Model::Serializable
attribute :req_if_content, ReqIfContent
xml do
- root "CORE-CONTENT"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "CORE-CONTENT"
+ namespace Namespace
+ ordered
map_element "REQ-IF-CONTENT", to: :req_if_content
end
diff --git a/lib/reqif/datatype_definition_boolean.rb b/lib/reqif/datatype_definition_boolean.rb
index 9619696..89b751b 100644
--- a/lib/reqif/datatype_definition_boolean.rb
+++ b/lib/reqif/datatype_definition_boolean.rb
@@ -9,10 +9,11 @@ class DatatypeDefinitionBoolean < Lutaml::Model::Serializable
attribute :alternative_id, AlternativeId
xml do
- root "DATATYPE-DEFINITION-BOOLEAN"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "DATATYPE-DEFINITION-BOOLEAN"
+ namespace Namespace
+ ordered
- map_attribute "DESC", to: :desc
+ map_attribute "DESC", to: :desc, render_empty: true
map_attribute "IDENTIFIER", to: :identifier
map_attribute "LAST-CHANGE", to: :last_change
map_attribute "LONG-NAME", to: :long_name
diff --git a/lib/reqif/datatype_definition_date.rb b/lib/reqif/datatype_definition_date.rb
index 3688af4..d29775a 100644
--- a/lib/reqif/datatype_definition_date.rb
+++ b/lib/reqif/datatype_definition_date.rb
@@ -9,10 +9,11 @@ class DatatypeDefinitionDate < Lutaml::Model::Serializable
attribute :alternative_id, AlternativeId
xml do
- root "DATATYPE-DEFINITION-DATE"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "DATATYPE-DEFINITION-DATE"
+ namespace Namespace
+ ordered
- map_attribute "DESC", to: :desc
+ map_attribute "DESC", to: :desc, render_empty: true
map_attribute "IDENTIFIER", to: :identifier
map_attribute "LAST-CHANGE", to: :last_change
map_attribute "LONG-NAME", to: :long_name
diff --git a/lib/reqif/datatype_definition_enumeration.rb b/lib/reqif/datatype_definition_enumeration.rb
index ecb002e..88aaddf 100644
--- a/lib/reqif/datatype_definition_enumeration.rb
+++ b/lib/reqif/datatype_definition_enumeration.rb
@@ -10,10 +10,11 @@ class DatatypeDefinitionEnumeration < Lutaml::Model::Serializable
attribute :specified_values, SpecifiedValues
xml do
- root "DATATYPE-DEFINITION-ENUMERATION"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "DATATYPE-DEFINITION-ENUMERATION"
+ namespace Namespace
+ ordered
- map_attribute "DESC", to: :desc
+ map_attribute "DESC", to: :desc, render_empty: true
map_attribute "IDENTIFIER", to: :identifier
map_attribute "LAST-CHANGE", to: :last_change
map_attribute "LONG-NAME", to: :long_name
diff --git a/lib/reqif/datatype_definition_integer.rb b/lib/reqif/datatype_definition_integer.rb
index 5ad47b6..4488d50 100644
--- a/lib/reqif/datatype_definition_integer.rb
+++ b/lib/reqif/datatype_definition_integer.rb
@@ -6,15 +6,16 @@ class DatatypeDefinitionInteger < Lutaml::Model::Serializable
attribute :identifier, :string
attribute :last_change, HighPrecisionDateTime
attribute :long_name, :string
- attribute :max, :integer
- attribute :min, :integer
+ attribute :max, ReqifInteger
+ attribute :min, ReqifInteger
attribute :alternative_id, AlternativeId
xml do
- root "DATATYPE-DEFINITION-INTEGER"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "DATATYPE-DEFINITION-INTEGER"
+ namespace Namespace
+ ordered
- map_attribute "DESC", to: :desc
+ map_attribute "DESC", to: :desc, render_empty: true
map_attribute "IDENTIFIER", to: :identifier
map_attribute "LAST-CHANGE", to: :last_change
map_attribute "LONG-NAME", to: :long_name
diff --git a/lib/reqif/datatype_definition_real.rb b/lib/reqif/datatype_definition_real.rb
index 0a5a6a6..8e3f1cc 100644
--- a/lib/reqif/datatype_definition_real.rb
+++ b/lib/reqif/datatype_definition_real.rb
@@ -7,16 +7,17 @@ class DatatypeDefinitionReal < Lutaml::Model::Serializable
attribute :identifier, :string
attribute :last_change, HighPrecisionDateTime
attribute :long_name, :string
- attribute :max, :float
- attribute :min, :float
+ attribute :max, ReqifFloat
+ attribute :min, ReqifFloat
attribute :alternative_id, AlternativeId
xml do
- root "DATATYPE-DEFINITION-REAL"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "DATATYPE-DEFINITION-REAL"
+ namespace Namespace
+ ordered
map_attribute "ACCURACY", to: :accuracy
- map_attribute "DESC", to: :desc
+ map_attribute "DESC", to: :desc, render_empty: true
map_attribute "IDENTIFIER", to: :identifier
map_attribute "LAST-CHANGE", to: :last_change
map_attribute "LONG-NAME", to: :long_name
diff --git a/lib/reqif/datatype_definition_string.rb b/lib/reqif/datatype_definition_string.rb
index 7ddcefa..9d148a8 100644
--- a/lib/reqif/datatype_definition_string.rb
+++ b/lib/reqif/datatype_definition_string.rb
@@ -10,10 +10,11 @@ class DatatypeDefinitionString < Lutaml::Model::Serializable
attribute :alternative_id, AlternativeId
xml do
- root "DATATYPE-DEFINITION-STRING"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "DATATYPE-DEFINITION-STRING"
+ namespace Namespace
+ ordered
- map_attribute "DESC", to: :desc
+ map_attribute "DESC", to: :desc, render_empty: true
map_attribute "IDENTIFIER", to: :identifier
map_attribute "LAST-CHANGE", to: :last_change
map_attribute "LONG-NAME", to: :long_name
diff --git a/lib/reqif/datatype_definition_xhtml.rb b/lib/reqif/datatype_definition_xhtml.rb
index 3de612c..3445c36 100644
--- a/lib/reqif/datatype_definition_xhtml.rb
+++ b/lib/reqif/datatype_definition_xhtml.rb
@@ -9,10 +9,11 @@ class DatatypeDefinitionXhtml < Lutaml::Model::Serializable
attribute :alternative_id, AlternativeId
xml do
- root "DATATYPE-DEFINITION-XHTML"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "DATATYPE-DEFINITION-XHTML"
+ namespace Namespace
+ ordered
- map_attribute "DESC", to: :desc
+ map_attribute "DESC", to: :desc, render_empty: true
map_attribute "IDENTIFIER", to: :identifier
map_attribute "LAST-CHANGE", to: :last_change
map_attribute "LONG-NAME", to: :long_name
diff --git a/lib/reqif/datatypes.rb b/lib/reqif/datatypes.rb
index c5ad431..3c35ff9 100644
--- a/lib/reqif/datatypes.rb
+++ b/lib/reqif/datatypes.rb
@@ -2,22 +2,33 @@
module Reqif
class Datatypes < Lutaml::Model::Serializable
- attribute :datatype_definition_boolean, DatatypeDefinitionBoolean, collection: true
- attribute :datatype_definition_date, DatatypeDefinitionDate, collection: true
- attribute :datatype_definition_enumeration, DatatypeDefinitionEnumeration, collection: true
- attribute :datatype_definition_integer, DatatypeDefinitionInteger, collection: true
- attribute :datatype_definition_real, DatatypeDefinitionReal, collection: true
- attribute :datatype_definition_string, DatatypeDefinitionString, collection: true
- attribute :datatype_definition_xhtml, DatatypeDefinitionXhtml, collection: true
+ attribute :datatype_definition_boolean, DatatypeDefinitionBoolean,
+ collection: true
+ attribute :datatype_definition_date, DatatypeDefinitionDate,
+ collection: true
+ attribute :datatype_definition_enumeration, DatatypeDefinitionEnumeration,
+ collection: true
+ attribute :datatype_definition_integer, DatatypeDefinitionInteger,
+ collection: true
+ attribute :datatype_definition_real, DatatypeDefinitionReal,
+ collection: true
+ attribute :datatype_definition_string, DatatypeDefinitionString,
+ collection: true
+ attribute :datatype_definition_xhtml, DatatypeDefinitionXhtml,
+ collection: true
xml do
- root "DATATYPES", ordered: true
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "DATATYPES"
+ namespace Namespace
+ ordered
- map_element "DATATYPE-DEFINITION-BOOLEAN", to: :datatype_definition_boolean
+ map_element "DATATYPE-DEFINITION-BOOLEAN",
+ to: :datatype_definition_boolean
map_element "DATATYPE-DEFINITION-DATE", to: :datatype_definition_date
- map_element "DATATYPE-DEFINITION-ENUMERATION", to: :datatype_definition_enumeration
- map_element "DATATYPE-DEFINITION-INTEGER", to: :datatype_definition_integer
+ map_element "DATATYPE-DEFINITION-ENUMERATION",
+ to: :datatype_definition_enumeration
+ map_element "DATATYPE-DEFINITION-INTEGER",
+ to: :datatype_definition_integer
map_element "DATATYPE-DEFINITION-REAL", to: :datatype_definition_real
map_element "DATATYPE-DEFINITION-STRING", to: :datatype_definition_string
map_element "DATATYPE-DEFINITION-XHTML", to: :datatype_definition_xhtml
diff --git a/lib/reqif/default_value.rb b/lib/reqif/default_value.rb
index c15f35a..0092c0f 100644
--- a/lib/reqif/default_value.rb
+++ b/lib/reqif/default_value.rb
@@ -11,13 +11,14 @@ class DefaultValue < Lutaml::Model::Serializable
attribute :attribute_value_xhtml, AttributeValueXhtml
xml do
- root "DEFAULT-VALUE"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "DEFAULT-VALUE"
+ namespace Namespace
# TODO: Only one of these values can be active at the same time
map_element "ATTRIBUTE-VALUE-BOOLEAN", to: :attribute_value_boolean
map_element "ATTRIBUTE-VALUE-DATE", to: :attribute_value_date
- map_element "ATTRIBUTE-VALUE-ENUMERATION", to: :attribute_value_enumeration
+ map_element "ATTRIBUTE-VALUE-ENUMERATION",
+ to: :attribute_value_enumeration
map_element "ATTRIBUTE-VALUE-INTEGER", to: :attribute_value_integer
map_element "ATTRIBUTE-VALUE-REAL", to: :attribute_value_real
map_element "ATTRIBUTE-VALUE-STRING", to: :attribute_value_string
diff --git a/lib/reqif/definition.rb b/lib/reqif/definition.rb
index 1c65d9c..b836552 100644
--- a/lib/reqif/definition.rb
+++ b/lib/reqif/definition.rb
@@ -2,26 +2,34 @@
module Reqif
class Definition < Lutaml::Model::Serializable
- attribute :attribute_definition_boolean_ref, :string
- attribute :attribute_definition_date_ref, :string
- attribute :attribute_definition_enumeration_ref, :string
- attribute :attribute_definition_integer_ref, :string
- attribute :attribute_definition_real_ref, :string
- attribute :attribute_definition_string_ref, :string
- attribute :attribute_definition_xhtml_ref, :string
+ attribute :attribute_definition_boolean_ref, ::Reqif::StringType
+ attribute :attribute_definition_date_ref, ::Reqif::StringType
+ attribute :attribute_definition_enumeration_ref, ::Reqif::StringType
+ attribute :attribute_definition_integer_ref, ::Reqif::StringType
+ attribute :attribute_definition_real_ref, ::Reqif::StringType
+ attribute :attribute_definition_string_ref, ::Reqif::StringType
+ attribute :attribute_definition_xhtml_ref, ::Reqif::StringType
xml do
- root "DEFINITION"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "DEFINITION"
+ namespace Namespace
+ ordered
# TODO: Only one of these values can be active at the same time
- map_element "ATTRIBUTE-DEFINITION-BOOLEAN-REF", to: :attribute_definition_boolean_ref
- map_element "ATTRIBUTE-DEFINITION-DATE-REF", to: :attribute_definition_date_ref
- map_element "ATTRIBUTE-DEFINITION-ENUMERATION-REF", to: :attribute_definition_enumeration_ref
- map_element "ATTRIBUTE-DEFINITION-INTEGER-REF", to: :attribute_definition_integer_ref
- map_element "ATTRIBUTE-DEFINITION-REAL-REF", to: :attribute_definition_real_ref
- map_element "ATTRIBUTE-DEFINITION-STRING-REF", to: :attribute_definition_string_ref
- map_element "ATTRIBUTE-DEFINITION-XHTML-REF", to: :attribute_definition_xhtml_ref
+ map_element "ATTRIBUTE-DEFINITION-BOOLEAN-REF",
+ to: :attribute_definition_boolean_ref
+ map_element "ATTRIBUTE-DEFINITION-DATE-REF",
+ to: :attribute_definition_date_ref
+ map_element "ATTRIBUTE-DEFINITION-ENUMERATION-REF",
+ to: :attribute_definition_enumeration_ref
+ map_element "ATTRIBUTE-DEFINITION-INTEGER-REF",
+ to: :attribute_definition_integer_ref
+ map_element "ATTRIBUTE-DEFINITION-REAL-REF",
+ to: :attribute_definition_real_ref
+ map_element "ATTRIBUTE-DEFINITION-STRING-REF",
+ to: :attribute_definition_string_ref
+ map_element "ATTRIBUTE-DEFINITION-XHTML-REF",
+ to: :attribute_definition_xhtml_ref
end
end
end
diff --git a/lib/reqif/doors.rb b/lib/reqif/doors.rb
new file mode 100644
index 0000000..a1382ba
--- /dev/null
+++ b/lib/reqif/doors.rb
@@ -0,0 +1,12 @@
+require "lutaml/model"
+
+module Reqif
+ module Doors
+ autoload :Namespace, "#{__dir__}/doors/namespace.rb"
+ autoload :Identifier, "#{__dir__}/doors/identifier.rb"
+ autoload :ModuleDefinition, "#{__dir__}/doors/module_definition.rb"
+ autoload :RifDefinition, "#{__dir__}/doors/rif_definition.rb"
+ autoload :ReadonlyAttributes, "#{__dir__}/doors/readonly_attributes.rb"
+ autoload :StringType, "#{__dir__}/doors/string_type.rb"
+ end
+end
diff --git a/lib/reqif/doors/identifier.rb b/lib/reqif/doors/identifier.rb
new file mode 100644
index 0000000..2506358
--- /dev/null
+++ b/lib/reqif/doors/identifier.rb
@@ -0,0 +1,15 @@
+require "lutaml/model"
+
+module Reqif
+ module Doors
+ class Identifier < Lutaml::Model::Serializable
+ attribute :content, :string
+
+ xml do
+ element "IDENTIFIER"
+ namespace Namespace
+ map_content to: :content
+ end
+ end
+ end
+end
diff --git a/lib/reqif/doors/module_definition.rb b/lib/reqif/doors/module_definition.rb
new file mode 100644
index 0000000..faaf7e7
--- /dev/null
+++ b/lib/reqif/doors/module_definition.rb
@@ -0,0 +1,23 @@
+require "lutaml/model"
+
+module Reqif
+ module Doors
+ class ModuleDefinition < Lutaml::Model::Serializable
+ #
+ # DDC_FULL_MODULE
+ # _3166b6de-d4b9-4334-a13f-a55792546604
+ #
+
+ attribute :ddc_mode, :string
+ attribute :specification_ref, ::Reqif::Doors::StringType
+
+ xml do
+ element "MODULE-DEFINITION"
+ namespace Namespace
+
+ map_element "DDC-MODE", to: :ddc_mode
+ map_element "SPECIFICATION-REF", to: :specification_ref
+ end
+ end
+ end
+end
diff --git a/lib/reqif/doors/namespace.rb b/lib/reqif/doors/namespace.rb
new file mode 100644
index 0000000..25e746d
--- /dev/null
+++ b/lib/reqif/doors/namespace.rb
@@ -0,0 +1,10 @@
+require "lutaml/model"
+
+module Reqif
+ module Doors
+ class Namespace < Lutaml::Xml::Namespace
+ uri "http://www.ibm.com/rdm/doors/REQIF/xmlns/1.0"
+ prefix_default "doors"
+ end
+ end
+end
diff --git a/lib/reqif/doors/readonly_attributes.rb b/lib/reqif/doors/readonly_attributes.rb
new file mode 100644
index 0000000..a6479c9
--- /dev/null
+++ b/lib/reqif/doors/readonly_attributes.rb
@@ -0,0 +1,48 @@
+require "lutaml/model"
+
+module Reqif
+ module Doors
+ class ReadonlyAttributes < Lutaml::Model::Serializable
+ #
+ # rmf-0d13686b-83c4-487b-9bcc-2f11a673c97a
+ # rmf-b5ff951b-70fc-440f-b775-cda530e97083
+ # rmf-0c2fc6c9-50e9-43ae-970b-c04ab506d834
+
+ attribute :attribute_definition_boolean_ref, ::Reqif::Doors::StringType,
+ collection: true
+ attribute :attribute_definition_date_ref, ::Reqif::Doors::StringType,
+ collection: true
+ attribute :attribute_definition_enumeration_ref,
+ ::Reqif::Doors::StringType, collection: true
+ attribute :attribute_definition_integer_ref, ::Reqif::Doors::StringType,
+ collection: true
+ attribute :attribute_definition_real_ref, ::Reqif::Doors::StringType,
+ collection: true
+ attribute :attribute_definition_string_ref, ::Reqif::Doors::StringType,
+ collection: true
+ attribute :attribute_definition_xhtml_ref, ::Reqif::Doors::StringType,
+ collection: true
+
+ xml do
+ element "READONLY-ATTRIBUTES"
+ namespace ::Reqif::Doors::Namespace
+ ordered
+
+ map_element "ATTRIBUTE-DEFINITION-BOOLEAN-REF",
+ to: :attribute_definition_boolean_ref
+ map_element "ATTRIBUTE-DEFINITION-DATE-REF",
+ to: :attribute_definition_date_ref
+ map_element "ATTRIBUTE-DEFINITION-ENUMERATION-REF",
+ to: :attribute_definition_enumeration_ref
+ map_element "ATTRIBUTE-DEFINITION-INTEGER-REF",
+ to: :attribute_definition_integer_ref
+ map_element "ATTRIBUTE-DEFINITION-REAL-REF",
+ to: :attribute_definition_real_ref
+ map_element "ATTRIBUTE-DEFINITION-STRING-REF",
+ to: :attribute_definition_string_ref
+ map_element "ATTRIBUTE-DEFINITION-XHTML-REF",
+ to: :attribute_definition_xhtml_ref
+ end
+ end
+ end
+end
diff --git a/lib/reqif/doors/rif_definition.rb b/lib/reqif/doors/rif_definition.rb
new file mode 100644
index 0000000..ea6527c
--- /dev/null
+++ b/lib/reqif/doors/rif_definition.rb
@@ -0,0 +1,26 @@
+require "lutaml/model"
+
+module Reqif
+ module Doors
+ class RifDefinition < Lutaml::Model::Serializable
+ #
+ # _ae71eb64-2aa6-4780-9212-bda594614a7f
+ #
+ # DDC_FULL_MODULE
+ # _3166b6de-d4b9-4334-a13f-a55792546604
+ #
+ #
+
+ attribute :identifier, ::Reqif::Doors::Identifier
+ attribute :module_definition, ::Reqif::Doors::ModuleDefinition
+
+ xml do
+ element "DOORS-RIF-DEFINITION"
+ namespace ::Reqif::Doors::Namespace
+
+ map_element "IDENTIFIER", to: :identifier
+ map_element "MODULE-DEFINITION", to: :module_definition
+ end
+ end
+ end
+end
diff --git a/lib/reqif/doors/string_type.rb b/lib/reqif/doors/string_type.rb
new file mode 100644
index 0000000..4b144a8
--- /dev/null
+++ b/lib/reqif/doors/string_type.rb
@@ -0,0 +1,12 @@
+module Reqif
+ module Doors
+ # String type that uses the ReqIF namespace, not Doors namespace.
+ # This is because elements like ATTRIBUTE-DEFINITION-*-REF inside
+ # Doors elements like READONLY-ATTRIBUTES still belong to the ReqIF namespace.
+ class StringType < Lutaml::Model::Type::String
+ xml do
+ namespace ::Reqif::Namespace
+ end
+ end
+ end
+end
diff --git a/lib/reqif/editable_atts.rb b/lib/reqif/editable_atts.rb
index de3faf5..04024c1 100644
--- a/lib/reqif/editable_atts.rb
+++ b/lib/reqif/editable_atts.rb
@@ -2,25 +2,33 @@
module Reqif
class EditableAtts < Lutaml::Model::Serializable
- attribute :attribute_definition_boolean_ref, :string, collection: true
- attribute :attribute_definition_date_ref, :string, collection: true
- attribute :attribute_definition_enumeration_ref, :string, collection: true
- attribute :attribute_definition_integer_ref, :string, collection: true
- attribute :attribute_definition_real_ref, :string, collection: true
- attribute :attribute_definition_string_ref, :string, collection: true
- attribute :attribute_definition_xhtml_ref, :string, collection: true
+ attribute :attribute_definition_boolean_ref, StringType, collection: true
+ attribute :attribute_definition_date_ref, StringType, collection: true
+ attribute :attribute_definition_enumeration_ref, StringType,
+ collection: true
+ attribute :attribute_definition_integer_ref, StringType, collection: true
+ attribute :attribute_definition_real_ref, StringType, collection: true
+ attribute :attribute_definition_string_ref, StringType, collection: true
+ attribute :attribute_definition_xhtml_ref, StringType, collection: true
xml do
- root "EDITABLE-ATTS"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "EDITABLE-ATTS"
+ namespace Namespace
- map_element "ATTRIBUTE-DEFINITION-BOOLEAN-REF", to: :attribute_definition_boolean_ref
- map_element "ATTRIBUTE-DEFINITION-DATE-REF", to: :attribute_definition_date_ref
- map_element "ATTRIBUTE-DEFINITION-ENUMERATION-REF", to: :attribute_definition_enumeration_ref
- map_element "ATTRIBUTE-DEFINITION-INTEGER-REF", to: :attribute_definition_integer_ref
- map_element "ATTRIBUTE-DEFINITION-REAL-REF", to: :attribute_definition_real_ref
- map_element "ATTRIBUTE-DEFINITION-STRING-REF", to: :attribute_definition_string_ref
- map_element "ATTRIBUTE-DEFINITION-XHTML-REF", to: :attribute_definition_xhtml_ref
+ map_element "ATTRIBUTE-DEFINITION-BOOLEAN-REF",
+ to: :attribute_definition_boolean_ref
+ map_element "ATTRIBUTE-DEFINITION-DATE-REF",
+ to: :attribute_definition_date_ref
+ map_element "ATTRIBUTE-DEFINITION-ENUMERATION-REF",
+ to: :attribute_definition_enumeration_ref
+ map_element "ATTRIBUTE-DEFINITION-INTEGER-REF",
+ to: :attribute_definition_integer_ref
+ map_element "ATTRIBUTE-DEFINITION-REAL-REF",
+ to: :attribute_definition_real_ref
+ map_element "ATTRIBUTE-DEFINITION-STRING-REF",
+ to: :attribute_definition_string_ref
+ map_element "ATTRIBUTE-DEFINITION-XHTML-REF",
+ to: :attribute_definition_xhtml_ref
end
end
end
diff --git a/lib/reqif/embedded_value.rb b/lib/reqif/embedded_value.rb
index 95bf450..44303d5 100644
--- a/lib/reqif/embedded_value.rb
+++ b/lib/reqif/embedded_value.rb
@@ -6,11 +6,12 @@ class EmbeddedValue < Lutaml::Model::Serializable
attribute :other_content, :string
xml do
- root "EMBEDDED-VALUE"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "EMBEDDED-VALUE"
+ namespace Namespace
+ ordered
map_attribute "KEY", to: :key
- map_attribute "OTHER-CONTENT", to: :other_content
+ map_attribute "OTHER-CONTENT", to: :other_content, render_empty: true
end
end
end
diff --git a/lib/reqif/enum_value.rb b/lib/reqif/enum_value.rb
index af1cd38..a23e88c 100644
--- a/lib/reqif/enum_value.rb
+++ b/lib/reqif/enum_value.rb
@@ -10,10 +10,10 @@ class EnumValue < Lutaml::Model::Serializable
attribute :properties, Properties
xml do
- root "ENUM-VALUE"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "ENUM-VALUE"
+ namespace Namespace
- map_attribute "DESC", to: :desc
+ map_attribute "DESC", to: :desc, render_empty: true
map_attribute "IDENTIFIER", to: :identifier
map_attribute "LAST-CHANGE", to: :last_change
map_attribute "LONG-NAME", to: :long_name
diff --git a/lib/reqif/high_precision_date_time.rb b/lib/reqif/high_precision_date_time.rb
index cec11b6..eafe13f 100644
--- a/lib/reqif/high_precision_date_time.rb
+++ b/lib/reqif/high_precision_date_time.rb
@@ -1,16 +1,52 @@
+# frozen_string_literal: true
+
require "lutaml/model/type/date_time"
module Reqif
+ # High precision DateTime type that preserves fractional seconds precision
class HighPrecisionDateTime < Lutaml::Model::Type::DateTime
+ attr_accessor :precision, :has_explicit_timezone
+
+ def initialize(value = nil)
+ super
+ @precision = 0
+ end
# The format looks like this `2012-04-07T01:51:37.112+02:00`
+ # or this `2021-07-01T01:12:06.749Z`
def self.from_xml(xml_string)
- ::DateTime.parse(xml_string)
+ new(::DateTime.parse(xml_string)).tap do |date_time|
+ date_time.precision = extract_precision(xml_string)
+ date_time.has_explicit_timezone = xml_string.match?(/[Zz]|[+-]\d{2}:\d{2}$/)
+ end
+ end
+
+ # Extract the precision of the milliseconds from the XML string
+ def self.extract_precision(xml_string)
+ if xml_string.include?(".")
+ milliseconds_part = xml_string.split(".").last.split(/Z|\+|-/).first
+ milliseconds_part.length
+ else
+ 0
+ end
end
- # The %L adds milliseconds to the time
def to_xml
- value.strftime("%Y-%m-%dT%H:%M:%S.%L99999%:z")
+ base = "%Y-%m-%dT%H:%M:%S"
+ pattern = precision.positive? ? "#{base}.%#{precision}N" : base
+ if has_explicit_timezone
+ value.offset.zero? ? value.strftime("#{pattern}Z") : value.strftime("#{pattern}%:z")
+ else
+ value.strftime(pattern)
+ end
+ end
+
+ def iso8601(precision = nil)
+ if precision.nil? || precision.zero?
+ value.iso8601
+ else
+ value.strftime("%Y-%m-%dT%H:%M:%S.%#{precision}N%z")
+ end
end
end
end
diff --git a/lib/reqif/namespace.rb b/lib/reqif/namespace.rb
new file mode 100644
index 0000000..a254862
--- /dev/null
+++ b/lib/reqif/namespace.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+require "lutaml/xml/namespace"
+
+module Reqif
+ # Namespace class for ReqIF XML elements.
+ # Supports alias URIs for backwards compatibility with different ReqIF versions.
+ # ReqIF 1.1 uses http://www.omg.org/spec/ReqIF/20110401/reqif.xsd
+ # Some older tools (e.g., Eclipse RMF) used http://www.omg.org/spec/ReqIF/20101201
+ class Namespace < Lutaml::Xml::Namespace
+ uri "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ uri_aliases "http://www.omg.org/spec/ReqIF/20101201"
+ element_form_default :qualified
+ attribute_form_default :qualified
+ end
+end
diff --git a/lib/reqif/object.rb b/lib/reqif/object.rb
index 5ca7fc0..7dec4cb 100644
--- a/lib/reqif/object.rb
+++ b/lib/reqif/object.rb
@@ -2,11 +2,11 @@
module Reqif
class Object < Lutaml::Model::Serializable
- attribute :spec_object_ref, :string
+ attribute :spec_object_ref, StringType
xml do
- root "OBJECT"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "OBJECT"
+ namespace Namespace
map_element "SPEC-OBJECT-REF", to: :spec_object_ref
end
diff --git a/lib/reqif/properties.rb b/lib/reqif/properties.rb
index ab7491f..bb1cc1e 100644
--- a/lib/reqif/properties.rb
+++ b/lib/reqif/properties.rb
@@ -5,8 +5,8 @@ class Properties < Lutaml::Model::Serializable
attribute :embedded_value, EmbeddedValue
xml do
- root "PROPERTIES"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "PROPERTIES"
+ namespace Namespace
map_element "EMBEDDED-VALUE", to: :embedded_value
end
diff --git a/lib/reqif/relation_group.rb b/lib/reqif/relation_group.rb
index 27cf6be..ec1d1c9 100644
--- a/lib/reqif/relation_group.rb
+++ b/lib/reqif/relation_group.rb
@@ -13,10 +13,11 @@ class RelationGroup < Lutaml::Model::Serializable
attribute :type, Type
xml do
- root "RELATION-GROUP"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "RELATION-GROUP"
+ namespace Namespace
+ ordered
- map_attribute "DESC", to: :desc
+ map_attribute "DESC", to: :desc, render_empty: true
map_attribute "IDENTIFIER", to: :identifier
map_attribute "LAST-CHANGE", to: :last_change
map_attribute "LONG-NAME", to: :long_name
diff --git a/lib/reqif/relation_group_type.rb b/lib/reqif/relation_group_type.rb
index 11bebdf..f08949e 100644
--- a/lib/reqif/relation_group_type.rb
+++ b/lib/reqif/relation_group_type.rb
@@ -10,10 +10,11 @@ class RelationGroupType < Lutaml::Model::Serializable
attribute :spec_attributes, SpecAttributes
xml do
- root "RELATION-GROUP-TYPE"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "RELATION-GROUP-TYPE"
+ namespace Namespace
+ ordered
- map_attribute "DESC", to: :desc
+ map_attribute "DESC", to: :desc, render_empty: true
map_attribute "IDENTIFIER", to: :identifier
map_attribute "LAST-CHANGE", to: :last_change
map_attribute "LONG-NAME", to: :long_name
diff --git a/lib/reqif/req_if.rb b/lib/reqif/req_if.rb
index c4766e1..94dbffc 100644
--- a/lib/reqif/req_if.rb
+++ b/lib/reqif/req_if.rb
@@ -1,17 +1,20 @@
require "lutaml/model"
+require "hyperlang"
module Reqif
class ReqIf < Lutaml::Model::Serializable
attribute :the_header, TheHeader
attribute :core_content, CoreContent
attribute :tool_extensions, ToolExtensions
- attribute :lang, :string
+ attribute :lang, Lutaml::Xml::W3c::XmlLangType
xml do
- root "REQ-IF"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "REQ-IF"
+ namespace Namespace
+ namespace_scope [Xhtml::Namespace]
+ ordered
- map_attribute "lang", to: :lang, namespace: "http://www.w3.org/XML/1998/namespace", prefix: "xml"
+ map_attribute "lang", to: :lang
map_element "THE-HEADER", to: :the_header
map_element "CORE-CONTENT", to: :core_content
map_element "TOOL-EXTENSIONS", to: :tool_extensions
diff --git a/lib/reqif/req_if_content.rb b/lib/reqif/req_if_content.rb
index 397cf3f..194f1ed 100644
--- a/lib/reqif/req_if_content.rb
+++ b/lib/reqif/req_if_content.rb
@@ -10,8 +10,9 @@ class ReqIfContent < Lutaml::Model::Serializable
attribute :spec_relation_groups, SpecRelationGroups
xml do
- root "REQ-IF-CONTENT"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "REQ-IF-CONTENT"
+ namespace Namespace
+ ordered
map_element "DATATYPES", to: :datatypes
map_element "SPEC-TYPES", to: :spec_types
diff --git a/lib/reqif/req_if_header.rb b/lib/reqif/req_if_header.rb
index 7c1c7f9..9f541bd 100644
--- a/lib/reqif/req_if_header.rb
+++ b/lib/reqif/req_if_header.rb
@@ -2,7 +2,7 @@ module Reqif
class ReqIfHeader < Lutaml::Model::Serializable
attribute :identifier, :string
attribute :comment, :string
- attribute :creation_time, :date_time
+ attribute :creation_time, HighPrecisionDateTime
attribute :repository_id, :string
attribute :req_if_tool_id, :string
attribute :req_if_version, :string
@@ -10,8 +10,9 @@ class ReqIfHeader < Lutaml::Model::Serializable
attribute :title, :string
xml do
- root "REQ-IF-HEADER", ordered: true
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "REQ-IF-HEADER"
+ namespace Namespace
+ ordered
map_attribute "IDENTIFIER", to: :identifier
map_element "COMMENT", to: :comment
diff --git a/lib/reqif/req_if_tool_extension.rb b/lib/reqif/req_if_tool_extension.rb
index a19d1d7..7b98daa 100644
--- a/lib/reqif/req_if_tool_extension.rb
+++ b/lib/reqif/req_if_tool_extension.rb
@@ -2,9 +2,55 @@
module Reqif
class ReqIfToolExtension < Lutaml::Model::Serializable
+ #
+ # _ae71eb64-2aa6-4780-9212-bda594614a7f
+ #
+ # DDC_FULL_MODULE
+ # _3166b6de-d4b9-4334-a13f-a55792546604
+ #
+ #
+
+ #
+ # rmf-0d13686b-83c4-487b-9bcc-2f11a673c97a
+
+ # rmf-48ed4896-28e9-492a-a45a-ca3716a64632
+
+ # rmf-b5ff951b-70fc-440f-b775-cda530e97083
+
+ # rmf-81da08a0-6257-488b-b373-04d59395c81a
+
+ # rmf-0c2fc6c9-50e9-43ae-970b-c04ab506d834
+
+ # rmf-f0d39171-054d-43e9-aec3-810b47c32334
+
+ # rmf-34c59c32-81d4-43ef-99be-a445358cd4bd
+
+ # rmf-d683201b-4545-4afc-beee-401855fa2ded
+
+ # rmf-baad7651-7ec7-4694-8913-68daa9927781
+
+ # rmf-ee42329b-d592-44fb-91d2-469a9a9b9dce
+
+ # rmf-47a379f0-441b-4df1-bbd8-a4281b890c26
+
+ # rmf-5c6c023c-8ace-4f68-807b-80190ba90552
+
+ # rmf-6b83e957-ff2c-4de6-8bf8-4d2549d0d7bc
+
+ # rmf-a8329820-0ccd-4ebf-8701-a2fd599dc463
+
+ # rmf-012fb471-e36e-4785-91e6-fdb754ad3613
+ #
+
+ attribute :doors_rif_definition, ::Reqif::Doors::RifDefinition
+ attribute :readonly_attributes, ::Reqif::Doors::ReadonlyAttributes
+
xml do
- root "REQ-IF-TOOL-EXTENSION"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "REQ-IF-TOOL-EXTENSION"
+ namespace Namespace
+
+ map_element "DOORS-RIF-DEFINITION", to: :doors_rif_definition
+ map_element "READONLY-ATTRIBUTES", to: :readonly_attributes
end
end
end
diff --git a/lib/reqif/reqif_float.rb b/lib/reqif/reqif_float.rb
new file mode 100644
index 0000000..4c029f7
--- /dev/null
+++ b/lib/reqif/reqif_float.rb
@@ -0,0 +1,97 @@
+# frozen_string_literal: true
+
+require "bigdecimal"
+require "lutaml/model/type/float"
+
+module Reqif
+ # Custom Float type that handles ReqIF float serialization.
+ # Preserves decimal notation for simple values and uses scientific
+ # notation only when necessary (very large/small numbers).
+ class ReqifFloat < Lutaml::Model::Type::Float
+ # Format a float value for ReqIF.
+ # Uses decimal notation for values that can be represented cleanly,
+ # otherwise uses scientific notation with uppercase E.
+ #
+ # @param f [Float] The float value
+ # @return [String] ReqIF formatted string
+ def self.reqif_format(float_value)
+ # Try to represent as a clean decimal first
+ decimal_str = format_float_as_decimal(float_value)
+ return decimal_str if decimal_str
+
+ # Fall back to scientific notation
+ format_scientific(float_value)
+ end
+
+ # Format as decimal if it can be done cleanly
+ def self.format_float_as_decimal(float_value)
+ # Use a reasonable precision to avoid floating point artifacts
+ # Check if the value can be represented cleanly in decimal
+ decimal_str = format("%.10g", float_value)
+
+ # Skip if it's in scientific notation (contains 'e' or 'E')
+ return nil if decimal_str.include?("e") || decimal_str.include?("E")
+
+ # Verify round-trip: parse back and check if we get the same value
+ parsed = BigDecimal(decimal_str).to_f
+ return decimal_str if parsed == float_value
+
+ # Try with higher precision
+ decimal_str = format("%.15g", float_value)
+ return nil if decimal_str.include?("e") || decimal_str.include?("E")
+
+ parsed = BigDecimal(decimal_str).to_f
+ return decimal_str if parsed == float_value
+
+ nil # Couldn't represent cleanly
+ end
+
+ # Format in scientific notation
+ def self.format_scientific(float_value)
+ formatted = format("%.15e", float_value).upcase
+ mantissa, exp = formatted.split("E")
+
+ # Strip trailing zeros from mantissa
+ mantissa = mantissa.sub(/\.?0+$/, "")
+ mantissa = "0" if mantissa.empty?
+ # Remove decimal point if it becomes trailing (e.g. "1.")
+ mantissa = mantissa.chomp(".")
+
+ # Handle exponent sign and strip leading zeros
+ sign = exp.start_with?("-") ? "-" : ""
+ digits = exp.sub(/^[+-]/, "").sub(/\A0+/, "")
+ digits = "0" if digits.empty?
+
+ "#{mantissa}E#{sign}#{digits}"
+ end
+
+ def self.cast(value, options = {})
+ return nil if value.nil?
+
+ unless options.equal?(EMPTY_OPTIONS)
+ Lutaml::Model::Services::Type::Validator::Number.validate!(value,
+ options)
+ end
+
+ case value
+ when String then BigDecimal(value).to_f
+ when Float then value
+ when BigDecimal then value.to_f
+ else Float(value.to_s)
+ end
+ end
+
+ def self.to_xml(value)
+ return nil if value.nil?
+
+ result = cast(value)
+ return nil if result.nil?
+
+ reqif_format(result)
+ end
+
+ def to_xml
+ self.class.to_xml(value)
+ end
+ end
+end
diff --git a/lib/reqif/reqif_integer.rb b/lib/reqif/reqif_integer.rb
new file mode 100644
index 0000000..ad3ec51
--- /dev/null
+++ b/lib/reqif/reqif_integer.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+require "bigdecimal"
+require "lutaml/model/type/decimal"
+
+module Reqif
+ # Custom Integer type using BigDecimal internally to support
+ # arbitrary precision integers beyond Ruby's native 64-bit range.
+ # Serializes without a decimal point for ReqIF compatibility.
+ class ReqifInteger < Lutaml::Model::Type::Decimal
+ def self.cast(value, options = {})
+ return nil if value.nil?
+
+ result = super
+ return nil if result.nil?
+
+ result
+ end
+
+ # Serialize to XML as a plain integer (no decimal point, no fractional part).
+ # Uses BigDecimal#to_i to strip any fractional part, ensuring output
+ # matches ReqIF's integer format.
+ def self.to_xml(value)
+ return nil if value.nil?
+
+ result = cast(value)
+ return nil if result.nil?
+
+ result.to_i.to_s
+ end
+
+ def to_xml
+ self.class.to_xml(value)
+ end
+ end
+end
diff --git a/lib/reqif/source.rb b/lib/reqif/source.rb
index 4f79157..8123872 100644
--- a/lib/reqif/source.rb
+++ b/lib/reqif/source.rb
@@ -2,11 +2,11 @@
module Reqif
class Source < Lutaml::Model::Serializable
- attribute :spec_object_ref, :string
+ attribute :spec_object_ref, StringType
xml do
- root "SOURCE"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "SOURCE"
+ namespace Namespace
map_element "SPEC-OBJECT-REF", to: :spec_object_ref
end
diff --git a/lib/reqif/source_specification.rb b/lib/reqif/source_specification.rb
index 6510dfa..74c324b 100644
--- a/lib/reqif/source_specification.rb
+++ b/lib/reqif/source_specification.rb
@@ -2,11 +2,11 @@
module Reqif
class SourceSpecification < Lutaml::Model::Serializable
- attribute :specification_ref, :string
+ attribute :specification_ref, StringType
xml do
- root "SOURCE-SPECIFICATION"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "SOURCE-SPECIFICATION"
+ namespace Namespace
map_element "SPECIFICATION-REF", to: :specification_ref
end
diff --git a/lib/reqif/spec_attributes.rb b/lib/reqif/spec_attributes.rb
index a52081c..518b0fd 100644
--- a/lib/reqif/spec_attributes.rb
+++ b/lib/reqif/spec_attributes.rb
@@ -2,24 +2,36 @@
module Reqif
class SpecAttributes < Lutaml::Model::Serializable
- attribute :attribute_definition_boolean, AttributeDefinitionBoolean, collection: true
- attribute :attribute_definition_date, AttributeDefinitionDate, collection: true
- attribute :attribute_definition_enumeration, AttributeDefinitionEnumeration, collection: true
- attribute :attribute_definition_integer, AttributeDefinitionInteger, collection: true
- attribute :attribute_definition_real, AttributeDefinitionReal, collection: true
- attribute :attribute_definition_string, AttributeDefinitionString, collection: true
- attribute :attribute_definition_xhtml, AttributeDefinitionXhtml, collection: true
+ attribute :attribute_definition_boolean, AttributeDefinitionBoolean,
+ collection: true
+ attribute :attribute_definition_date, AttributeDefinitionDate,
+ collection: true
+ attribute :attribute_definition_enumeration,
+ AttributeDefinitionEnumeration, collection: true
+ attribute :attribute_definition_integer, AttributeDefinitionInteger,
+ collection: true
+ attribute :attribute_definition_real, AttributeDefinitionReal,
+ collection: true
+ attribute :attribute_definition_string, AttributeDefinitionString,
+ collection: true
+ attribute :attribute_definition_xhtml, AttributeDefinitionXhtml,
+ collection: true
xml do
- root "SPEC-ATTRIBUTES"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "SPEC-ATTRIBUTES"
+ namespace Namespace
+ ordered
- map_element "ATTRIBUTE-DEFINITION-BOOLEAN", to: :attribute_definition_boolean
+ map_element "ATTRIBUTE-DEFINITION-BOOLEAN",
+ to: :attribute_definition_boolean
map_element "ATTRIBUTE-DEFINITION-DATE", to: :attribute_definition_date
- map_element "ATTRIBUTE-DEFINITION-ENUMERATION", to: :attribute_definition_enumeration
- map_element "ATTRIBUTE-DEFINITION-INTEGER", to: :attribute_definition_integer
+ map_element "ATTRIBUTE-DEFINITION-ENUMERATION",
+ to: :attribute_definition_enumeration
+ map_element "ATTRIBUTE-DEFINITION-INTEGER",
+ to: :attribute_definition_integer
map_element "ATTRIBUTE-DEFINITION-REAL", to: :attribute_definition_real
- map_element "ATTRIBUTE-DEFINITION-STRING", to: :attribute_definition_string
+ map_element "ATTRIBUTE-DEFINITION-STRING",
+ to: :attribute_definition_string
map_element "ATTRIBUTE-DEFINITION-XHTML", to: :attribute_definition_xhtml
end
end
diff --git a/lib/reqif/spec_hierarchy.rb b/lib/reqif/spec_hierarchy.rb
index b6a2a77..0b89d70 100644
--- a/lib/reqif/spec_hierarchy.rb
+++ b/lib/reqif/spec_hierarchy.rb
@@ -14,10 +14,11 @@ class SpecHierarchy < Lutaml::Model::Serializable
attribute :object, Object
xml do
- root "SPEC-HIERARCHY"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "SPEC-HIERARCHY"
+ namespace Namespace
+ ordered
- map_attribute "DESC", to: :desc
+ map_attribute "DESC", to: :desc, render_empty: true
map_attribute "IDENTIFIER", to: :identifier
map_attribute "IS-EDITABLE", to: :is_editable
map_attribute "IS-TABLE-INTERNAL", to: :is_table_internal
diff --git a/lib/reqif/spec_object.rb b/lib/reqif/spec_object.rb
index f2d34c1..b73797f 100644
--- a/lib/reqif/spec_object.rb
+++ b/lib/reqif/spec_object.rb
@@ -11,10 +11,11 @@ class SpecObject < Lutaml::Model::Serializable
attribute :type, Type
xml do
- root "SPEC-OBJECT"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "SPEC-OBJECT"
+ namespace Namespace
+ ordered
- map_attribute "DESC", to: :desc
+ map_attribute "DESC", to: :desc, render_empty: true
map_attribute "IDENTIFIER", to: :identifier
map_attribute "LAST-CHANGE", to: :last_change
map_attribute "LONG-NAME", to: :long_name
diff --git a/lib/reqif/spec_object_type.rb b/lib/reqif/spec_object_type.rb
index e98d415..6287de6 100644
--- a/lib/reqif/spec_object_type.rb
+++ b/lib/reqif/spec_object_type.rb
@@ -10,10 +10,11 @@ class SpecObjectType < Lutaml::Model::Serializable
attribute :spec_attributes, SpecAttributes
xml do
- root "SPEC-OBJECT-TYPE"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "SPEC-OBJECT-TYPE"
+ namespace Namespace
+ ordered
- map_attribute "DESC", to: :desc
+ map_attribute "DESC", to: :desc, render_empty: true
map_attribute "IDENTIFIER", to: :identifier
map_attribute "LAST-CHANGE", to: :last_change
map_attribute "LONG-NAME", to: :long_name
diff --git a/lib/reqif/spec_objects.rb b/lib/reqif/spec_objects.rb
index bca98f4..e20def4 100644
--- a/lib/reqif/spec_objects.rb
+++ b/lib/reqif/spec_objects.rb
@@ -5,8 +5,9 @@ class SpecObjects < Lutaml::Model::Serializable
attribute :spec_object, SpecObject, collection: true
xml do
- root "SPEC-OBJECTS"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "SPEC-OBJECTS"
+ namespace Namespace
+ ordered
map_element "SPEC-OBJECT", to: :spec_object
end
diff --git a/lib/reqif/spec_relation.rb b/lib/reqif/spec_relation.rb
index ff3f63c..b9bc7cd 100644
--- a/lib/reqif/spec_relation.rb
+++ b/lib/reqif/spec_relation.rb
@@ -13,10 +13,11 @@ class SpecRelation < Lutaml::Model::Serializable
attribute :type, Type
xml do
- root "SPEC-RELATION"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "SPEC-RELATION"
+ namespace Namespace
+ ordered
- map_attribute "DESC", to: :desc
+ map_attribute "DESC", to: :desc, render_empty: true
map_attribute "IDENTIFIER", to: :identifier
map_attribute "LAST-CHANGE", to: :last_change
map_attribute "LONG-NAME", to: :long_name
diff --git a/lib/reqif/spec_relation_groups.rb b/lib/reqif/spec_relation_groups.rb
index 9ef213e..2e84851 100644
--- a/lib/reqif/spec_relation_groups.rb
+++ b/lib/reqif/spec_relation_groups.rb
@@ -5,8 +5,8 @@ class SpecRelationGroups < Lutaml::Model::Serializable
attribute :relation_group, RelationGroup, collection: true
xml do
- root "SPEC-RELATION-GROUPS"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "SPEC-RELATION-GROUPS"
+ namespace Namespace
map_element "RELATION-GROUP", to: :relation_group
end
diff --git a/lib/reqif/spec_relation_type.rb b/lib/reqif/spec_relation_type.rb
index 3c0e28b..ff7ac12 100644
--- a/lib/reqif/spec_relation_type.rb
+++ b/lib/reqif/spec_relation_type.rb
@@ -10,10 +10,11 @@ class SpecRelationType < Lutaml::Model::Serializable
attribute :spec_attributes, SpecAttributes
xml do
- root "SPEC-RELATION-TYPE"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "SPEC-RELATION-TYPE"
+ namespace Namespace
+ ordered
- map_attribute "DESC", to: :desc
+ map_attribute "DESC", to: :desc, render_empty: true
map_attribute "IDENTIFIER", to: :identifier
map_attribute "LAST-CHANGE", to: :last_change
map_attribute "LONG-NAME", to: :long_name
diff --git a/lib/reqif/spec_relations.rb b/lib/reqif/spec_relations.rb
index b9a79cd..3a4ef39 100644
--- a/lib/reqif/spec_relations.rb
+++ b/lib/reqif/spec_relations.rb
@@ -3,11 +3,11 @@
module Reqif
class SpecRelations < Lutaml::Model::Serializable
attribute :spec_relation, SpecRelation, collection: true
- attribute :spec_relation_ref, :string, collection: true
+ attribute :spec_relation_ref, StringType, collection: true
xml do
- root "SPEC-RELATIONS"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "SPEC-RELATIONS"
+ namespace Namespace
# TODO: Only one of these values can be active at the same time
map_element "SPEC-RELATION", to: :spec_relation
diff --git a/lib/reqif/spec_types.rb b/lib/reqif/spec_types.rb
index 3e707ea..e1b1ce4 100644
--- a/lib/reqif/spec_types.rb
+++ b/lib/reqif/spec_types.rb
@@ -8,8 +8,9 @@ class SpecTypes < Lutaml::Model::Serializable
attribute :specification_type, SpecificationType, collection: true
xml do
- root "SPEC-TYPES"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "SPEC-TYPES"
+ namespace Namespace
+ ordered
map_element "RELATION-GROUP-TYPE", to: :relation_group_type
map_element "SPEC-OBJECT-TYPE", to: :spec_object_type
diff --git a/lib/reqif/specification.rb b/lib/reqif/specification.rb
index ad20dff..59b8a4d 100644
--- a/lib/reqif/specification.rb
+++ b/lib/reqif/specification.rb
@@ -12,10 +12,11 @@ class Specification < Lutaml::Model::Serializable
attribute :type, Type
xml do
- root "SPECIFICATION"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "SPECIFICATION"
+ namespace Namespace
+ ordered
- map_attribute "DESC", to: :desc
+ map_attribute "DESC", to: :desc, render_empty: true
map_attribute "IDENTIFIER", to: :identifier
map_attribute "LAST-CHANGE", to: :last_change
map_attribute "LONG-NAME", to: :long_name
diff --git a/lib/reqif/specification_type.rb b/lib/reqif/specification_type.rb
index b8ca86b..30ccbe0 100644
--- a/lib/reqif/specification_type.rb
+++ b/lib/reqif/specification_type.rb
@@ -10,10 +10,11 @@ class SpecificationType < Lutaml::Model::Serializable
attribute :spec_attributes, SpecAttributes
xml do
- root "SPECIFICATION-TYPE"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "SPECIFICATION-TYPE"
+ namespace Namespace
+ ordered
- map_attribute "DESC", to: :desc
+ map_attribute "DESC", to: :desc, render_empty: true
map_attribute "IDENTIFIER", to: :identifier
map_attribute "LAST-CHANGE", to: :last_change
map_attribute "LONG-NAME", to: :long_name
diff --git a/lib/reqif/specifications.rb b/lib/reqif/specifications.rb
index 94b2cb5..073d23e 100644
--- a/lib/reqif/specifications.rb
+++ b/lib/reqif/specifications.rb
@@ -5,8 +5,9 @@ class Specifications < Lutaml::Model::Serializable
attribute :specification, Specification, collection: true
xml do
- root "SPECIFICATIONS"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "SPECIFICATIONS"
+ namespace Namespace
+ ordered
map_element "SPECIFICATION", to: :specification
end
diff --git a/lib/reqif/specified_values.rb b/lib/reqif/specified_values.rb
index 4aa71ed..0c020d3 100644
--- a/lib/reqif/specified_values.rb
+++ b/lib/reqif/specified_values.rb
@@ -5,8 +5,8 @@ class SpecifiedValues < Lutaml::Model::Serializable
attribute :enum_value, EnumValue, collection: true
xml do
- root "SPECIFIED-VALUES"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "SPECIFIED-VALUES"
+ namespace Namespace
map_element "ENUM-VALUE", to: :enum_value
end
diff --git a/lib/reqif/string_type.rb b/lib/reqif/string_type.rb
new file mode 100644
index 0000000..0f7ded6
--- /dev/null
+++ b/lib/reqif/string_type.rb
@@ -0,0 +1,7 @@
+module Reqif
+ class StringType < Lutaml::Model::Type::String
+ xml do
+ namespace Namespace
+ end
+ end
+end
diff --git a/lib/reqif/target.rb b/lib/reqif/target.rb
index dde65bc..476c050 100644
--- a/lib/reqif/target.rb
+++ b/lib/reqif/target.rb
@@ -2,11 +2,11 @@
module Reqif
class Target < Lutaml::Model::Serializable
- attribute :spec_object_ref, :string
+ attribute :spec_object_ref, StringType
xml do
- root "TARGET"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "TARGET"
+ namespace Namespace
map_element "SPEC-OBJECT-REF", to: :spec_object_ref
end
diff --git a/lib/reqif/target_specification.rb b/lib/reqif/target_specification.rb
index d5a89c1..6fa3b14 100644
--- a/lib/reqif/target_specification.rb
+++ b/lib/reqif/target_specification.rb
@@ -2,11 +2,11 @@
module Reqif
class TargetSpecification < Lutaml::Model::Serializable
- attribute :specification_ref, :string
+ attribute :specification_ref, StringType
xml do
- root "TARGET-SPECIFICATION"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "TARGET-SPECIFICATION"
+ namespace Namespace
map_element "SPECIFICATION-REF", to: :specification_ref
end
diff --git a/lib/reqif/the_header.rb b/lib/reqif/the_header.rb
index 36ee9cb..40c746d 100644
--- a/lib/reqif/the_header.rb
+++ b/lib/reqif/the_header.rb
@@ -5,8 +5,9 @@ class TheHeader < Lutaml::Model::Serializable
attribute :req_if_header, ReqIfHeader
xml do
- root "THE-HEADER"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "THE-HEADER"
+ namespace Namespace
+ ordered
map_element "REQ-IF-HEADER", to: :req_if_header
end
diff --git a/lib/reqif/tool_extensions.rb b/lib/reqif/tool_extensions.rb
index 1e0f6e9..12c9a3e 100644
--- a/lib/reqif/tool_extensions.rb
+++ b/lib/reqif/tool_extensions.rb
@@ -5,8 +5,8 @@ class ToolExtensions < Lutaml::Model::Serializable
attribute :req_if_tool_extension, ReqIfToolExtension, collection: true
xml do
- root "TOOL-EXTENSIONS"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "TOOL-EXTENSIONS"
+ namespace Namespace
map_element "REQ-IF-TOOL-EXTENSION", to: :req_if_tool_extension
end
diff --git a/lib/reqif/type.rb b/lib/reqif/type.rb
index ba658ca..5f42e0d 100644
--- a/lib/reqif/type.rb
+++ b/lib/reqif/type.rb
@@ -2,32 +2,40 @@
module Reqif
class Type < Lutaml::Model::Serializable
- attribute :datatype_definition_boolean_ref, :string
- attribute :specification_type_ref, :string
- attribute :relation_group_type_ref, :string
- attribute :datatype_definition_date_ref, :string
- attribute :datatype_definition_enumeration_ref, :string
- attribute :datatype_definition_integer_ref, :string
- attribute :datatype_definition_real_ref, :string
- attribute :datatype_definition_string_ref, :string
- attribute :datatype_definition_xhtml_ref, :string
- attribute :spec_object_type_ref, :string
- attribute :spec_relation_type_ref, :string
+ attribute :datatype_definition_boolean_ref, StringType
+ attribute :specification_type_ref, StringType
+ attribute :relation_group_type_ref, StringType
+ attribute :datatype_definition_date_ref, StringType
+ attribute :datatype_definition_enumeration_ref, StringType
+ attribute :datatype_definition_integer_ref, StringType
+ attribute :datatype_definition_real_ref, StringType
+ attribute :datatype_definition_string_ref, StringType
+ attribute :datatype_definition_xhtml_ref, StringType
+ attribute :spec_object_type_ref, StringType
+ attribute :spec_relation_type_ref, StringType
xml do
- root "TYPE"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "TYPE"
+ namespace Namespace
+ ordered
# TODO: Only one of these values can be active at the same time
- map_element "DATATYPE-DEFINITION-BOOLEAN-REF", to: :datatype_definition_boolean_ref
+ map_element "DATATYPE-DEFINITION-BOOLEAN-REF",
+ to: :datatype_definition_boolean_ref
map_element "SPECIFICATION-TYPE-REF", to: :specification_type_ref
map_element "RELATION-GROUP-TYPE-REF", to: :relation_group_type_ref
- map_element "DATATYPE-DEFINITION-DATE-REF", to: :datatype_definition_date_ref
- map_element "DATATYPE-DEFINITION-ENUMERATION-REF", to: :datatype_definition_enumeration_ref
- map_element "DATATYPE-DEFINITION-INTEGER-REF", to: :datatype_definition_integer_ref
- map_element "DATATYPE-DEFINITION-REAL-REF", to: :datatype_definition_real_ref
- map_element "DATATYPE-DEFINITION-STRING-REF", to: :datatype_definition_string_ref
- map_element "DATATYPE-DEFINITION-XHTML-REF", to: :datatype_definition_xhtml_ref
+ map_element "DATATYPE-DEFINITION-DATE-REF",
+ to: :datatype_definition_date_ref
+ map_element "DATATYPE-DEFINITION-ENUMERATION-REF",
+ to: :datatype_definition_enumeration_ref
+ map_element "DATATYPE-DEFINITION-INTEGER-REF",
+ to: :datatype_definition_integer_ref
+ map_element "DATATYPE-DEFINITION-REAL-REF",
+ to: :datatype_definition_real_ref
+ map_element "DATATYPE-DEFINITION-STRING-REF",
+ to: :datatype_definition_string_ref
+ map_element "DATATYPE-DEFINITION-XHTML-REF",
+ to: :datatype_definition_xhtml_ref
map_element "SPEC-OBJECT-TYPE-REF", to: :spec_object_type_ref
map_element "SPEC-RELATION-TYPE-REF", to: :spec_relation_type_ref
end
diff --git a/lib/reqif/values.rb b/lib/reqif/values.rb
index 6dd92f3..ac8ca3e 100644
--- a/lib/reqif/values.rb
+++ b/lib/reqif/values.rb
@@ -4,21 +4,24 @@ module Reqif
class Values < Lutaml::Model::Serializable
attribute :attribute_value_boolean, AttributeValueBoolean, collection: true
attribute :attribute_value_date, AttributeValueDate, collection: true
- attribute :attribute_value_enumeration, AttributeValueEnumeration, collection: true
+ attribute :attribute_value_enumeration, AttributeValueEnumeration,
+ collection: true
attribute :attribute_value_integer, AttributeValueInteger, collection: true
attribute :attribute_value_real, AttributeValueReal, collection: true
attribute :attribute_value_string, AttributeValueString, collection: true
attribute :attribute_value_xhtml, AttributeValueXhtml, collection: true
- attribute :enum_value_ref, :string, collection: true
+ attribute :enum_value_ref, StringType, collection: true
# TODO: if ENUM-VALUE-REF is present, all others cannot be present.
xml do
- root "VALUES"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "VALUES"
+ namespace Namespace
+ ordered
map_element "ATTRIBUTE-VALUE-BOOLEAN", to: :attribute_value_boolean
map_element "ATTRIBUTE-VALUE-DATE", to: :attribute_value_date
- map_element "ATTRIBUTE-VALUE-ENUMERATION", to: :attribute_value_enumeration
+ map_element "ATTRIBUTE-VALUE-ENUMERATION",
+ to: :attribute_value_enumeration
map_element "ATTRIBUTE-VALUE-INTEGER", to: :attribute_value_integer
map_element "ATTRIBUTE-VALUE-REAL", to: :attribute_value_real
map_element "ATTRIBUTE-VALUE-STRING", to: :attribute_value_string
diff --git a/lib/reqif/xhtml.rb b/lib/reqif/xhtml.rb
new file mode 100644
index 0000000..14dbdd2
--- /dev/null
+++ b/lib/reqif/xhtml.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+require "lutaml/model"
+
+module Reqif
+ module Xhtml
+ autoload :Namespace, "#{__dir__}/xhtml/namespace.rb"
+ autoload :Div, "#{__dir__}/xhtml/div.rb"
+ autoload :Span, "#{__dir__}/xhtml/span.rb"
+ autoload :P, "#{__dir__}/xhtml/p.rb"
+ end
+end
diff --git a/lib/reqif/xhtml/div.rb b/lib/reqif/xhtml/div.rb
new file mode 100644
index 0000000..92b8885
--- /dev/null
+++ b/lib/reqif/xhtml/div.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+require "lutaml/model"
+
+module Reqif
+ module Xhtml
+ class Div < Lutaml::Model::Serializable
+ attribute :content, :string
+
+ xml do
+ element "div"
+ namespace Namespace
+
+ map_content to: :content
+ end
+ end
+ end
+end
diff --git a/lib/reqif/xhtml/namespace.rb b/lib/reqif/xhtml/namespace.rb
new file mode 100644
index 0000000..557c302
--- /dev/null
+++ b/lib/reqif/xhtml/namespace.rb
@@ -0,0 +1,10 @@
+require "lutaml/model"
+
+module Reqif
+ module Xhtml
+ class Namespace < Lutaml::Xml::Namespace
+ uri "http://www.w3.org/1999/xhtml"
+ prefix_default "xhtml"
+ end
+ end
+end
diff --git a/lib/reqif/xhtml/p.rb b/lib/reqif/xhtml/p.rb
new file mode 100644
index 0000000..b6e2659
--- /dev/null
+++ b/lib/reqif/xhtml/p.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+require "lutaml/model"
+
+module Reqif
+ module Xhtml
+ class P < Lutaml::Model::Serializable
+ attribute :content, :string
+
+ xml do
+ element "p"
+ namespace Namespace
+
+ map_content to: :content
+ end
+ end
+ end
+end
diff --git a/lib/reqif/xhtml/span.rb b/lib/reqif/xhtml/span.rb
new file mode 100644
index 0000000..606bacf
--- /dev/null
+++ b/lib/reqif/xhtml/span.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+require "lutaml/model"
+
+module Reqif
+ module Xhtml
+ class Span < Lutaml::Model::Serializable
+ attribute :content, :string
+
+ xml do
+ element "span"
+ namespace Namespace
+
+ map_content to: :content
+ end
+ end
+ end
+end
diff --git a/lib/reqif/xhtml_content.rb b/lib/reqif/xhtml_content.rb
index 1f7cae9..efdc5a1 100644
--- a/lib/reqif/xhtml_content.rb
+++ b/lib/reqif/xhtml_content.rb
@@ -1,10 +1,190 @@
+# frozen_string_literal: true
+
require "lutaml/model"
module Reqif
class XhtmlContent < Lutaml::Model::Serializable
+ # All XHTML block and inline elements that can appear in XHTML-CONTENT
+ attribute :div, Hyperlang::Xhtml::Div, collection: true
+ attribute :p, Hyperlang::Xhtml::P, collection: true
+ attribute :span, Hyperlang::Xhtml::Span, collection: true
+ attribute :br, Hyperlang::Xhtml::Br, collection: true
+ attribute :strong, Hyperlang::Xhtml::Strong, collection: true
+ attribute :em, Hyperlang::Xhtml::Em, collection: true
+ attribute :ul, Hyperlang::Xhtml::Ul, collection: true
+ attribute :ol, Hyperlang::Xhtml::Ol, collection: true
+ attribute :li, Hyperlang::Xhtml::Li, collection: true
+ attribute :a, Hyperlang::Xhtml::A, collection: true
+ attribute :h1, Hyperlang::Xhtml::H1, collection: true
+ attribute :h2, Hyperlang::Xhtml::H2, collection: true
+ attribute :h3, Hyperlang::Xhtml::H3, collection: true
+ attribute :h4, Hyperlang::Xhtml::H4, collection: true
+ attribute :h5, Hyperlang::Xhtml::H5, collection: true
+ attribute :h6, Hyperlang::Xhtml::H6, collection: true
+ attribute :img, Hyperlang::Xhtml::Img, collection: true
+ attribute :blockquote, Hyperlang::Xhtml::Blockquote, collection: true
+ attribute :pre, Hyperlang::Xhtml::Pre, collection: true
+ attribute :code, Hyperlang::Xhtml::Code, collection: true
+ attribute :dl, Hyperlang::Xhtml::Dl, collection: true
+ attribute :dt, Hyperlang::Xhtml::Dt, collection: true
+ attribute :dd, Hyperlang::Xhtml::Dd, collection: true
+ attribute :table, Hyperlang::Xhtml::Table, collection: true
+ attribute :tr, Hyperlang::Xhtml::Tr, collection: true
+ attribute :th, Hyperlang::Xhtml::Th, collection: true
+ attribute :td, Hyperlang::Xhtml::Td, collection: true
+ attribute :thead, Hyperlang::Xhtml::Thead, collection: true
+ attribute :tbody, Hyperlang::Xhtml::Tbody, collection: true
+ attribute :tfoot, Hyperlang::Xhtml::Tfoot, collection: true
+ attribute :caption, Hyperlang::Xhtml::Caption, collection: true
+ attribute :form, Hyperlang::Xhtml::Form, collection: true
+ attribute :input, Hyperlang::Xhtml::Input, collection: true
+ attribute :select, Hyperlang::Xhtml::Select, collection: true
+ attribute :option, Hyperlang::Xhtml::Option, collection: true
+ attribute :textarea, Hyperlang::Xhtml::Textarea, collection: true
+ attribute :button, Hyperlang::Xhtml::Button, collection: true
+ attribute :label, Hyperlang::Xhtml::Label, collection: true
+ attribute :fieldset, Hyperlang::Xhtml::Fieldset, collection: true
+ attribute :legend, Hyperlang::Xhtml::Legend, collection: true
+ attribute :hr, Hyperlang::Xhtml::Hr, collection: true
+ attribute :address, Hyperlang::Xhtml::Address, collection: true
+ attribute :b, Hyperlang::Xhtml::B, collection: true
+ attribute :i, Hyperlang::Xhtml::I, collection: true
+ attribute :u, Hyperlang::Xhtml::U, collection: true
+ attribute :s, Hyperlang::Xhtml::S, collection: true
+ attribute :strike, Hyperlang::Xhtml::Strike, collection: true
+ attribute :big, Hyperlang::Xhtml::Big, collection: true
+ attribute :small, Hyperlang::Xhtml::Small, collection: true
+ attribute :sub, Hyperlang::Xhtml::Sub, collection: true
+ attribute :sup, Hyperlang::Xhtml::Sup, collection: true
+ attribute :tt, Hyperlang::Xhtml::Tt, collection: true
+ attribute :abbr, Hyperlang::Xhtml::Abbr, collection: true
+ attribute :acronym, Hyperlang::Xhtml::Acronym, collection: true
+ attribute :cite, Hyperlang::Xhtml::Cite, collection: true
+ attribute :code, Hyperlang::Xhtml::Code, collection: true
+ attribute :dfn, Hyperlang::Xhtml::Dfn, collection: true
+ attribute :kbd, Hyperlang::Xhtml::Kbd, collection: true
+ attribute :samp, Hyperlang::Xhtml::Samp, collection: true
+ attribute :var, Hyperlang::Xhtml::Var, collection: true
+ attribute :q, Hyperlang::Xhtml::Q, collection: true
+ attribute :del, Hyperlang::Xhtml::Del, collection: true
+ attribute :ins, Hyperlang::Xhtml::Ins, collection: true
+ attribute :noscript, Hyperlang::Xhtml::Noscript, collection: true
+ attribute :script, Hyperlang::Xhtml::Script, collection: true
+ attribute :map, Hyperlang::Xhtml::Map, collection: true
+ attribute :area, Hyperlang::Xhtml::Area, collection: true
+ attribute :object, Hyperlang::Xhtml::Object, collection: true
+ attribute :param, Hyperlang::Xhtml::Param, collection: true
+ attribute :col, Hyperlang::Xhtml::Col, collection: true
+ attribute :colgroup, Hyperlang::Xhtml::Colgroup, collection: true
+ attribute :ruby, Hyperlang::Xhtml::Ruby, collection: true
+ attribute :rb, Hyperlang::Xhtml::Rb, collection: true
+ attribute :rt, Hyperlang::Xhtml::Rt, collection: true
+ attribute :rp, Hyperlang::Xhtml::Rp, collection: true
+ attribute :rbc, Hyperlang::Xhtml::Rbc, collection: true
+ attribute :rtc, Hyperlang::Xhtml::Rtc, collection: true
+ attribute :content, :string
+
xml do
- root "XHTML-CONTENT"
- namespace "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
+ element "XHTML-CONTENT"
+ namespace Namespace
+ mixed_content
+ map_content to: :content
+
+ # Block and structural elements
+ map_element "div", to: :div
+ map_element "p", to: :p
+ map_element "h1", to: :h1
+ map_element "h2", to: :h2
+ map_element "h3", to: :h3
+ map_element "h4", to: :h4
+ map_element "h5", to: :h5
+ map_element "h6", to: :h6
+ map_element "blockquote", to: :blockquote
+ map_element "pre", to: :pre
+ map_element "hr", to: :hr
+ map_element "address", to: :address
+
+ # Lists
+ map_element "ul", to: :ul
+ map_element "ol", to: :ol
+ map_element "li", to: :li
+ map_element "dl", to: :dl
+ map_element "dt", to: :dt
+ map_element "dd", to: :dd
+
+ # Tables
+ map_element "table", to: :table
+ map_element "caption", to: :caption
+ map_element "thead", to: :thead
+ map_element "tbody", to: :tbody
+ map_element "tfoot", to: :tfoot
+ map_element "tr", to: :tr
+ map_element "th", to: :th
+ map_element "td", to: :td
+ map_element "col", to: :col
+ map_element "colgroup", to: :colgroup
+
+ # Inline text elements
+ map_element "span", to: :span
+ map_element "br", to: :br
+ map_element "strong", to: :strong
+ map_element "em", to: :em
+ map_element "a", to: :a
+ map_element "img", to: :img
+ map_element "code", to: :code
+ map_element "q", to: :q
+ map_element "b", to: :b
+ map_element "i", to: :i
+ map_element "u", to: :u
+ map_element "s", to: :s
+ map_element "strike", to: :strike
+ map_element "big", to: :big
+ map_element "small", to: :small
+ map_element "sub", to: :sub
+ map_element "sup", to: :sup
+ map_element "tt", to: :tt
+ map_element "abbr", to: :abbr
+ map_element "acronym", to: :acronym
+ map_element "cite", to: :cite
+ map_element "dfn", to: :dfn
+ map_element "kbd", to: :kbd
+ map_element "samp", to: :samp
+ map_element "var", to: :var
+
+ # Forms
+ map_element "form", to: :form
+ map_element "input", to: :input
+ map_element "select", to: :select
+ map_element "option", to: :option
+ map_element "textarea", to: :textarea
+ map_element "button", to: :button
+ map_element "label", to: :label
+ map_element "fieldset", to: :fieldset
+ map_element "legend", to: :legend
+
+ # Edit elements
+ map_element "del", to: :del
+ map_element "ins", to: :ins
+
+ # Scripting
+ map_element "noscript", to: :noscript
+ map_element "script", to: :script
+
+ # Image map
+ map_element "map", to: :map
+ map_element "area", to: :area
+
+ # Object
+ map_element "object", to: :object
+ map_element "param", to: :param
+
+ # Ruby
+ map_element "ruby", to: :ruby
+ map_element "rb", to: :rb
+ map_element "rt", to: :rt
+ map_element "rp", to: :rp
+ map_element "rbc", to: :rbc
+ map_element "rtc", to: :rtc
end
end
end
diff --git a/reqif.gemspec b/reqif.gemspec
index caff890..07ba0c6 100644
--- a/reqif.gemspec
+++ b/reqif.gemspec
@@ -16,6 +16,7 @@ Gem::Specification.new do |spec|
spec.metadata["homepage_uri"] = spec.homepage
spec.metadata["source_code_uri"] = spec.homepage
spec.metadata["changelog_uri"] = "https://github.com/lutaml/reqif/releases"
+ spec.metadata["rubygems_mfa_required"] = "true"
# Specify which files should be added to the gem when it is released.
# The `git ls-files -z` loads the files in the RubyGem
@@ -31,6 +32,6 @@ Gem::Specification.new do |spec|
spec.required_ruby_version = ">= 3.0.0"
- spec.add_dependency "lutaml-model"
- spec.add_dependency "zeitwerk", "~> 2.6.18"
+ spec.add_dependency "hyperlang", "~> 0.1.1"
+ spec.add_dependency "lutaml-model", "~> 0.8.0"
end
diff --git a/spec/reqif/polarion_export_spec.rb b/spec/reqif/polarion_export_spec.rb
index 2035274..284e8c8 100644
--- a/spec/reqif/polarion_export_spec.rb
+++ b/spec/reqif/polarion_export_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
RSpec.describe "Polarion Export" do
let(:xml_file) { File.read("spec/fixtures/polarion_export.xml") }
let(:reqif) { Reqif::ReqIf.from_xml(xml_file) }
@@ -5,11 +7,16 @@
it "parses Polarion export correctly" do
expect(reqif.the_header.req_if_header.req_if_tool_id).to eq("Polarion")
- enum_type = reqif.core_content.req_if_content.datatypes.datatype_definition_enumeration.find { |d| d.long_name == "Status" }
- expect(enum_type).to_not be_nil
- expect(enum_type.specified_values.map(&:long_name)).to contain_exactly("Draft", "Approved")
+ enum_type = reqif.core_content.req_if_content.datatypes.datatype_definition_enumeration.find do |d|
+ d.long_name == "Status"
+ end
+ expect(enum_type).not_to be_nil
+ expect(enum_type.specified_values.enum_value.map(&:long_name)).to contain_exactly(
+ "Draft", "Approved"
+ )
- spec_object = reqif.req_if_content.spec_objects.spec_object.first
- expect(spec_object.values.first.the_value).to include("The system shall be able to handle concurrent users.")
+ spec_object = reqif.core_content.req_if_content.spec_objects.spec_object.first
+ xhtml_val = spec_object.values.attribute_value_xhtml.first
+ expect(xhtml_val.the_value).to be_a(Reqif::XhtmlContent)
end
end
diff --git a/spec/reqif/req_if_header_spec.rb b/spec/reqif/req_if_header_spec.rb
index 021a2e9..2afe4ab 100644
--- a/spec/reqif/req_if_header_spec.rb
+++ b/spec/reqif/req_if_header_spec.rb
@@ -1,10 +1,11 @@
+# frozen_string_literal: true
+
RSpec.describe Reqif::ReqIfHeader do
let(:header_xml) do
<<~XML
-
+
Example ReqIF file
2023-10-26T12:00:00Z
- _1234567890
reqif-tool
1.0
source-tool
@@ -18,8 +19,8 @@
describe "attributes" do
it "parses all header attributes" do
expect(header.comment).to eq("Example ReqIF file")
- expect(header.creation_time).to be_a(DateTime)
- expect(header.creation_time.utc.iso8601).to eq("2023-10-26T12:00:00Z")
+ expect(header.creation_time).to be_a(Reqif::HighPrecisionDateTime)
+ expect(header.creation_time.iso8601).to eq("2023-10-26T12:00:00+00:00")
expect(header.identifier).to eq("_1234567890")
expect(header.req_if_tool_id).to eq("reqif-tool")
expect(header.req_if_version).to eq("1.0")
diff --git a/spec/reqif/req_if_spec.rb b/spec/reqif/req_if_spec.rb
index fa62cd0..cdb6688 100644
--- a/spec/reqif/req_if_spec.rb
+++ b/spec/reqif/req_if_spec.rb
@@ -1,19 +1,22 @@
+# frozen_string_literal: true
+
require "spec_helper"
RSpec.describe Reqif::ReqIf do
- let(:xml_string) { File.read("spec/fixtures/strictdoc_01_minimal_reqif_sample.reqif") }
+ let(:xml_string) { File.read("spec/fixtures/eclipse_rmf_sample.reqif") }
let(:parsed) { described_class.from_xml(xml_string) }
describe ".from_xml" do
it "parses ReqIF XML correctly" do
expect(parsed).to be_a(described_class)
- expect(parsed.the_header).to be_a(Reqif::ReqIfHeader)
- expect(parsed.req_if_content).to be_a(Reqif::ReqIfContent)
+ expect(parsed.the_header.req_if_header).to be_a(Reqif::ReqIfHeader)
+ expect(parsed.core_content.req_if_content).to be_a(Reqif::ReqIfContent)
end
it "maintains XML namespaces" do
generated = parsed.to_xml
- expect(generated).to include('xmlns="http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"')
+ # Eclipse RMF fixtures use 20101201 namespace which should be preserved
+ expect(generated).to include('xmlns="http://www.omg.org/spec/ReqIF/20101201"')
end
end
@@ -34,7 +37,7 @@
# puts "------"
# puts generated
- expect(generated).to be_analogous_with(xml_string)
+ expect(generated).to be_xml_equivalent_to(xml_string)
end
end
end
diff --git a/spec/reqif/spec_objects_spec.rb b/spec/reqif/spec_objects_spec.rb
index 38dc4c8..103a4bf 100644
--- a/spec/reqif/spec_objects_spec.rb
+++ b/spec/reqif/spec_objects_spec.rb
@@ -1,13 +1,18 @@
+# frozen_string_literal: true
+
RSpec.describe Reqif::SpecObject do
let(:spec_object_xml) do
<<~XML
-
- st1
+
+
+ st1
+
-
- ad1
- System shall provide login functionality
-
+
+
+ ad1
+
+
XML
@@ -19,12 +24,11 @@
it "parses basic attributes" do
expect(spec_object.identifier).to eq("so1")
expect(spec_object.long_name).to eq("Login Requirement")
- expect(spec_object.type_ref).to eq("st1")
+ expect(spec_object.type.spec_object_type_ref).to eq("st1")
end
it "parses values" do
- value = spec_object.values.first
- expect(value.definition_ref).to eq("ad1")
+ value = spec_object.values.attribute_value_string.first
expect(value.the_value).to eq("System shall provide login functionality")
end
end
diff --git a/spec/reqif/spec_relations_spec.rb b/spec/reqif/spec_relations_spec.rb
index 8d6d03a..d64b8ac 100644
--- a/spec/reqif/spec_relations_spec.rb
+++ b/spec/reqif/spec_relations_spec.rb
@@ -1,11 +1,19 @@
+# frozen_string_literal: true
+
RSpec.describe Reqif::SpecRelations do
let(:spec_relations_xml) do
<<~XML
-
+
- so1
- so2
- rt1
+
+ so1
+
+
+ so2
+
+
+ rt1
+
XML
@@ -17,9 +25,9 @@
it "parses relation attributes" do
relation = spec_relations.spec_relation.first
expect(relation.identifier).to eq("rel1")
- expect(relation.source_ref).to eq("so1")
- expect(relation.target_ref).to eq("so2")
- expect(relation.type_ref).to eq("rt1")
+ expect(relation.source.spec_object_ref).to eq("so1")
+ expect(relation.target.spec_object_ref).to eq("so2")
+ expect(relation.type.spec_relation_type_ref).to eq("rt1")
end
end
end
diff --git a/spec/reqif/spec_types_spec.rb b/spec/reqif/spec_types_spec.rb
index d44ca1f..d77c8ee 100644
--- a/spec/reqif/spec_types_spec.rb
+++ b/spec/reqif/spec_types_spec.rb
@@ -1,15 +1,20 @@
+# frozen_string_literal: true
+
RSpec.describe Reqif::SpecTypes do
let(:spec_types_xml) do
<<~XML
-
+
-
+
- dt1
- No description provided
- false
+
+ dt1
+
+
+
+
-
+
XML
@@ -25,12 +30,11 @@
end
it "parses attribute definitions" do
- attr_def = spec_types.spec_object_type.first.attribute_definitions.first
+ attr_def = spec_types.spec_object_type.first.spec_attributes.attribute_definition_string.first
expect(attr_def.identifier).to eq("ad1")
expect(attr_def.long_name).to eq("Description")
- expect(attr_def.type_ref).to eq("dt1")
- expect(attr_def.default_value).to eq("No description provided")
- expect(attr_def.multi_valued).to be false
+ expect(attr_def.type.datatype_definition_string_ref).to eq("dt1")
+ expect(attr_def.default_value.attribute_value_string.the_value).to eq("No description provided")
end
end
end
diff --git a/spec/reqif/specifications_spec.rb b/spec/reqif/specifications_spec.rb
index 476d656..7b764fe 100644
--- a/spec/reqif/specifications_spec.rb
+++ b/spec/reqif/specifications_spec.rb
@@ -1,11 +1,15 @@
+# frozen_string_literal: true
+
RSpec.describe Reqif::Specifications do
let(:specifications_xml) do
<<~XML
-
+
- so1
+
@@ -23,9 +27,9 @@
end
it "parses spec hierarchy" do
- hierarchy = specifications.specification.first.children.first
+ hierarchy = specifications.specification.first.children.spec_hierarchy.first
expect(hierarchy.identifier).to eq("sh1")
- expect(hierarchy.object_ref).to eq("so1")
+ expect(hierarchy.object.spec_object_ref).to eq("so1")
end
end
end
diff --git a/spec/reqif/tool_extension_spec.rb b/spec/reqif/tool_extension_spec.rb
index 5872530..020297f 100644
--- a/spec/reqif/tool_extension_spec.rb
+++ b/spec/reqif/tool_extension_spec.rb
@@ -1,21 +1,27 @@
-RSpec.describe Reqif::ReqIfToolExtension do
- let(:tool_extension_xml) do
+# frozen_string_literal: true
+
+RSpec.describe Reqif::ToolExtensions do
+ let(:tool_extensions_xml) do
<<~XML
-
-
- custom-tool
- Custom data
+
+
+
+ _test-id
+
+ DDC_FULL_MODULE
+
+
XML
end
- let(:tool_extension) { described_class.from_xml(tool_extension_xml) }
+ let(:tool_extensions) { described_class.from_xml(tool_extensions_xml) }
describe "tool extensions" do
it "parses tool extension data" do
- expect(tool_extension.extensions).to be_a(Array)
- expect(tool_extension.extensions.first).to include("TOOL-ID" => "custom-tool")
+ ext = tool_extensions.req_if_tool_extension.first
+ expect(ext.doors_rif_definition.identifier.content).to eq("_test-id")
end
end
end
diff --git a/spec/reqif_spec.rb b/spec/reqif_spec.rb
index 42d3bd7..637e977 100644
--- a/spec/reqif_spec.rb
+++ b/spec/reqif_spec.rb
@@ -9,7 +9,7 @@
describe "XML round-trip conversion" do
xml_files = Dir[fixtures_dir.join("**", "*.xml")] +
- Dir[fixtures_dir.join("**", "*.reqif")]
+ Dir[fixtures_dir.join("**", "*.reqif")]
# def check_parsed_content(parsed, reparsed)
# %i[
@@ -48,19 +48,7 @@
encoding: "utf-8",
)
- # cleaned_xml_string = xml_string
- cleaned_xml_string = xml_string
- .gsub(/^<\?xml.*\n/, "")
- # cleaned_xml_string = xml_string
- # .gsub(/^<\?xml-model.*\n/, "")
- # .gsub(/^<\?xml-stylesheet.*\n/, "")
-
- # puts "original---------"
- # puts cleaned_xml_string
- # puts "------"
- # puts generated
-
- expect(generated).to be_analogous_with(cleaned_xml_string)
+ expect(generated).to be_xml_equivalent_to(xml_string)
end
end
end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index d4c204e..981a50a 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -2,7 +2,56 @@
require "reqif"
require "nokogiri"
-require "xml-c14n"
+require "canon/rspec_matchers"
+
+# Configure Canon to ignore XML comments (lutaml-model doesn't preserve them)
+# and structural whitespace (input/output formatting may differ)
+Canon::Config.configure do |config|
+ config.xml.match.options = {
+ comments: :ignore,
+ structural_whitespace: :ignore,
+ attribute_order: :ignore,
+ }
+end
+
+# Monkey-patch FormatPreservationRule to handle namespaces without prefix_default.
+# When a namespace URI is declared with a prefix in the input (e.g., xmlns:reqif="..."),
+# the preserved_input_format becomes :prefix. But if the Namespace class doesn't
+# define prefix_default, we fall back to :default format to avoid an error.
+module Lutaml
+ module Xml
+ module Decisions
+ module Rules
+ class FormatPreservationRule
+ alias_method :original_decide, :decide
+ def decide(context)
+ input_format = context.preserved_input_format
+
+ if input_format == :default
+ Decision.default(
+ namespace_class: context.namespace_class,
+ reason: "Priority 1: Input used default format - preserve it",
+ )
+ elsif context.namespace_class.prefix_default.nil?
+ # input_format is :prefix but prefix_default might be nil
+ # Fall back to default format to avoid ArgumentError
+ Decision.default(
+ namespace_class: context.namespace_class,
+ reason: "Priority 1: No prefix_default - use default format",
+ )
+ else
+ Decision.prefix(
+ prefix: context.namespace_class.prefix_default,
+ namespace_class: context.namespace_class,
+ reason: "Priority 1: Input used prefix format - preserve it",
+ )
+ end
+ end
+ end
+ end
+ end
+ end
+end
RSpec.configure do |config|
# Enable flags like --only-failures and --next-failure
@@ -16,13 +65,6 @@
end
end
-require "lutaml/model"
-require "lutaml/model/xml_adapter/nokogiri_adapter"
-require "lutaml/model/json_adapter/standard_json_adapter"
-require "lutaml/model/yaml_adapter/standard_yaml_adapter"
-
Lutaml::Model::Config.configure do |config|
- config.xml_adapter = Lutaml::Model::XmlAdapter::NokogiriAdapter
- config.json_adapter = Lutaml::Model::JsonAdapter::StandardJsonAdapter
- config.yaml_adapter = Lutaml::Model::YamlAdapter::StandardYamlAdapter
+ config.xml_adapter_type = :nokogiri
end