Class: PBCore::Element
- Inherits:
-
Object
- Object
- PBCore::Element
- Includes:
- Attributes::Common, SAXMachine
- Defined in:
- lib/pbcore/element.rb
Overview
TODO: decouple XML building behavior from schema-related declarations.
Direct Known Subclasses
Annotation, AssetDate, AssetType, AudienceLevel, AudienceRating, Contributor, Contributor::Contributor, Contributor::Role, Coverage, Coverage::Coverage, Coverage::Type, Creator, Creator::Creator, Creator::Role, Description, DescriptionDocument, Extension, PBCore::Extension::Embedded, PBCore::Extension::Wrap, PBCore::Extension::Wrap::Element, Genre, Identifier, Instantiation, Instantiation::AlternativeModes, Instantiation::Annotation, Instantiation::ChannelConfiguration, Instantiation::Colors, Instantiation::DataRate, Instantiation::Date, Instantiation::Digital, Instantiation::Dimensions, Instantiation::Duration, Instantiation::EssenceTrack, Instantiation::EssenceTrack::Annotation, Instantiation::EssenceTrack::AspectRatio, Instantiation::EssenceTrack::BitDepth, Instantiation::EssenceTrack::DataRate, Instantiation::EssenceTrack::Duration, Instantiation::EssenceTrack::Encoding, Instantiation::EssenceTrack::FrameRate, Instantiation::EssenceTrack::FrameSize, Instantiation::EssenceTrack::Identifier, Instantiation::EssenceTrack::Language, Instantiation::EssenceTrack::PlaybackSpeed, Instantiation::EssenceTrack::SamplingRate, Instantiation::EssenceTrack::Standard, Instantiation::EssenceTrack::TimeStart, Instantiation::EssenceTrack::Type, Instantiation::Extension, Instantiation::FileSize, Instantiation::Generations, Instantiation::Identifier, Instantiation::Language, Instantiation::Location, Instantiation::MediaType, Instantiation::Physical, Instantiation::Relation, Instantiation::Relation::Identifier, Instantiation::Relation::Type, Instantiation::Rights, Instantiation::Rights::Link, Instantiation::Rights::Summary, Instantiation::Standard, Instantiation::TimeStart, Instantiation::Tracks, InstantiationDocument, Publisher, Publisher::Publisher, Publisher::Role, Relation, Relation::Identifier, Relation::Type, RightsSummary, RightsSummary::Link, RightsSummary::Summary, Subject, Title
Class Attribute Summary collapse
-
.build_block ⇒ Object
readonly
Returns the value of attribute build_block.
Class Method Summary collapse
- .attribute_config ⇒ Object
-
.build_xml(&block) ⇒ Object
Class method to allow extended classes to declaratively the logic used to build XML using Nokogiri::XML::Builder.
- .element_config_all ⇒ Object
-
.element_config_for_value ⇒ Object
Returns the SAXMachine::SaxConfig::ElementConfig instance for the element that represents the value (i.e. text that is one or more child elements).
-
.element_config_has_many ⇒ Object
Returns the SAXMachine::SaxConfig::ElementConfig that allow for multiple instances of other elements.
-
.element_config_has_one ⇒ Object
Returns the SAXMachine::SaxConfig::ElementConfig instances that allow for a single instance of another element.
-
.has_a_value? ⇒ Boolean
Returns true if the element is configured to contain a value.
-
.has_many?(name, opts = {}) ⇒ Boolean
Returns true if the element is configured to contain many instances of a child element that matches the name and opts parameters.
-
.has_one?(name, opts = {}) ⇒ Boolean
Returns true if the element is configured to contain a single instance of a child element that matches the name and opts parameters.
- .has_sax_machine_attribute?(name, opts = {}) ⇒ Boolean
- .has_sax_machine_collection_element?(name, opts = {}) ⇒ Boolean
- .has_sax_machine_top_level_element?(name, opts = {}) ⇒ Boolean
- .has_sax_machine_value_element? ⇒ Boolean
Instance Method Summary collapse
-
#attributes(key_by_xml_name: false) ⇒ Object
Returns a hash of attrubutes as the should appear in the XML.
-
#build(builder = nil) ⇒ Object
Executes the block defined with the class method ‘build_xml`.
-
#elements(key_by_xml_name: false) ⇒ Object
Returns a hash of child element instances.
-
#to_xml ⇒ Object
Builds the xml using #build with a new instance of Nokogiri::XML::Builder and immediately calls to_xml on it.
-
#xml_attributes ⇒ Object
Shortcut for getting xml attributes.
Methods included from Attributes::Common
Class Attribute Details
.build_block ⇒ Object (readonly)
Returns the value of attribute build_block.
78 79 80 |
# File 'lib/pbcore/element.rb', line 78 def build_block @build_block end |
Class Method Details
.attribute_config ⇒ Object
115 116 117 |
# File 'lib/pbcore/element.rb', line 115 def attribute_config sax_config.top_level_attributes end |
.build_xml(&block) ⇒ Object
Class method to allow extended classes to declaratively the logic used to build XML using Nokogiri::XML::Builder.
82 83 84 85 |
# File 'lib/pbcore/element.rb', line 82 def build_xml(&block) raise ArgumentError, "#{self.class}.build_xml requires a block with one parameter" unless block_given? && block.arity == 1 @build_block = block end |
.element_config_all ⇒ Object
155 156 157 158 159 |
# File 'lib/pbcore/element.rb', line 155 def element_config_all element_config_has_one.merge(element_config_has_many) do |name, config_has_one, config_has_many| config_has_many.present? ? config_has_many : config_has_one end end |
.element_config_for_value ⇒ Object
Returns the SAXMachine::SaxConfig::ElementConfig instance for the element that represents the value (i.e. text that is one or more child elements). This is essentially the inverse of element_config_has_one.
135 136 137 138 139 140 141 |
# File 'lib/pbcore/element.rb', line 135 def element_config_for_value sax_config.top_level_elements.detect do |_name, element_configs| element_configs.detect do |element_config| element_config.instance_variable_get(:@as) == :value end end end |
.element_config_has_many ⇒ Object
Returns the SAXMachine::SaxConfig::ElementConfig that allow for multiple instances of other elements. NOTE: SAXMachine uses the term “collection” elements, but that’s very confusing since PBCoreCollection is a thing, so we change it to the has_many terminology (and has_one for the singular element config for consistency).
149 150 151 152 153 |
# File 'lib/pbcore/element.rb', line 149 def element_config_has_many sax_config.collection_elements.reject do |element_config| element_config.instance_variable_get(:@as) == :value end end |
.element_config_has_one ⇒ Object
Returns the SAXMachine::SaxConfig::ElementConfig instances that allow for a single instance of another element. NOTE: We use the “has_one” and “has_many” terminoolgy for child elements because it seems to be the most readable option.
123 124 125 126 127 128 129 |
# File 'lib/pbcore/element.rb', line 123 def element_config_has_one sax_config.top_level_elements.reject do |_name, element_configs| element_configs.detect do |element_config| element_config.instance_variable_get(:@as) == :value end end end |
.has_a_value? ⇒ Boolean
Returns true if the element is configured to contain a value.
111 112 113 |
# File 'lib/pbcore/element.rb', line 111 def has_a_value? !element_config_for_value.nil? end |
.has_many?(name, opts = {}) ⇒ Boolean
Returns true if the element is configured to contain many instances of a child element that matches the name and opts parameters.
102 103 104 105 106 107 108 |
# File 'lib/pbcore/element.rb', line 102 def has_many?(name, opts={}) element_config_has_many.any? do |element_config| opts.all? do |key, val| val == element_config.instance_variable_get(:"@#{key}") end end end |
.has_one?(name, opts = {}) ⇒ Boolean
Returns true if the element is configured to contain a single instance of a child element that matches the name and opts parameters.
89 90 91 92 93 94 95 96 97 98 |
# File 'lib/pbcore/element.rb', line 89 def has_one?(name, opts={}) element_config_has_one.any? do |element_config| opts.all? do |key, val| # In SAXMachine::SaxConfig::ElementConfig, the :class config option # maps to instance variable @data_class. key = :data_class if key == :class val == element_config.instance_variable_get(:"@#{key}") end end end |
.has_sax_machine_attribute?(name, opts = {}) ⇒ Boolean
161 162 163 164 165 166 167 |
# File 'lib/pbcore/element.rb', line 161 def has_sax_machine_attribute?(name, opts={}) sax_config.top_level_attributes.any? do |attr_config| opts.all? do |key, val| val == attr_config.instance_variable_get("@#{key}".to_sym) end end end |
.has_sax_machine_collection_element?(name, opts = {}) ⇒ Boolean
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
# File 'lib/pbcore/element.rb', line 182 def has_sax_machine_collection_element?(name, opts={}) # NOTE: Accessing collection_element configs with squarey brackets has # the unwanted side affect of creating an entry in the # collection_elements, which we don't want. So we use #fetch here Array(sax_config.collection_elements.fetch(name.to_s, nil)).any? do |element_config| opts.all? do |key, val| # This is a quirk of SAXMachine; for some reason it converts the # config option :as to a string when assigning it to the # ConfigElement instance, so we need to convert opts[:as] param to # string in order to compare them accurately. val = val.to_s if key == :as val == element_config.instance_variable_get(:"@#{key}") end end end |
.has_sax_machine_top_level_element?(name, opts = {}) ⇒ Boolean
173 174 175 176 177 178 179 180 |
# File 'lib/pbcore/element.rb', line 173 def has_sax_machine_top_level_element?(name, opts={}) Array(sax_config.top_level_elements.fetch(name.to_s, nil)).any? do |element_config| opts.all? do |key, val| key = :data_class if key == :class val == element_config.instance_variable_get("@#{key}".to_sym) end end end |
.has_sax_machine_value_element? ⇒ Boolean
169 170 171 |
# File 'lib/pbcore/element.rb', line 169 def has_sax_machine_value_element? !sax_config.top_level_element_value.empty? end |
Instance Method Details
#attributes(key_by_xml_name: false) ⇒ Object
Returns a hash of attrubutes as the should appear in the XML.
48 49 50 51 52 53 54 55 56 57 |
# File 'lib/pbcore/element.rb', line 48 def attributes(key_by_xml_name: false) xml_attrs = Hash[ self.class.sax_config.top_level_attributes.map do |attr| accessor = attr.instance_variable_get(:@as) key = key_by_xml_name ? attr.name : accessor [ key, send(accessor) ] end ] xml_attrs end |
#build(builder = nil) ⇒ Object
Executes the block defined with the class method ‘build_xml`. Uses a Nokogiri::XML::Builder instance (either passed in or instantiated) to build the XML, and then returns the builder instance.
62 63 64 65 66 67 68 |
# File 'lib/pbcore/element.rb', line 62 def build(builder=nil) raise ArgumentError, "#{self.class}#build expects a Nokogiri::XML::Builder class, but #{builder.class} was given" unless builder.nil? || builder.is_a?(Nokogiri::XML::Builder) PBCore.fail_if_missing_build_xml_block(element_class: self.class) builder ||= Nokogiri::XML::Builder.new instance_exec builder, &self.class.build_block builder end |
#elements(key_by_xml_name: false) ⇒ Object
Returns a hash of child element instances.
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/pbcore/element.rb', line 26 def elements(key_by_xml_name: false) key_value_pairs_array = self.class.element_config_all.map do |name, element_configs| # SAXMachine allows you to declare multiple elements with the same name # but we don't do tha with PBCore, so just grab the first and only one. element_config = element_configs.first # get the accessor name by which to get the value accessor = element_config.instance_variable_get(:@as) # fetch the value by calling the accessor value = send(accessor) # create the key, value pair that will go into the Hash[] construct. key = key_by_xml_name ? name : accessor [ key, value ] end Hash[ key_value_pairs_array ] end |
#to_xml ⇒ Object
Builds the xml using #build with a new instance of Nokogiri::XML::Builder and immediately calls to_xml on it.
72 73 74 |
# File 'lib/pbcore/element.rb', line 72 def to_xml build.to_xml end |
#xml_attributes ⇒ Object
Shortcut for getting xml attributes.
45 |
# File 'lib/pbcore/element.rb', line 45 def xml_attributes; attributes(key_by_xml_name: true); end |