Class: PBCore::Element
- Inherits:
-
Object
- Object
- PBCore::Element
- Includes:
- SAXMachine
- Defined in:
- lib/pbcore/element.rb
Overview
TODO: decouple XML building behavior from schema-related declarations.
Direct Known Subclasses
ContentElement, Contributor, Coverage, Coverage::Type, Creator, DescriptionDocument, Extension, PBCore::Extension::Wrap, PBCore::Extension::Wrap::Element, Instantiation, Instantiation::EssenceTrack, Instantiation::Extension, Instantiation::Relation, Instantiation::Rights, InstantiationDocument, Publisher, Relation, RightsSummary
Class Attribute Summary collapse
-
.build_block ⇒ Object
readonly
Returns the value of attribute build_block.
Class Method Summary collapse
- .all_element_config ⇒ Object
- .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.
-
.collection_element_config ⇒ Object
Returns the SAXMachine::SaxConfig::ElementConfig that allow for multiple instances of other elements, i.e.
-
.has_a_value? ⇒ Boolean
Returns true if the element is configured to contain a value.
- .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
-
.top_level_element_config ⇒ Object
Returns the SAXMachine::SaxConfig::ElementConfig instances that allow for a single instance of another element.
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.
Class Attribute Details
.build_block ⇒ Object (readonly)
Returns the value of attribute build_block.
72 73 74 |
# File 'lib/pbcore/element.rb', line 72 def build_block @build_block end |
Class Method Details
.all_element_config ⇒ Object
109 110 111 112 113 |
# File 'lib/pbcore/element.rb', line 109 def all_element_config top_level_element_config.merge(collection_element_config) do |name, top_level_element_cfg, coll_element_cfg| coll_element_cfg.present? ? coll_element_cfg : top_level_element_cfg end end |
.attribute_config ⇒ Object
81 82 83 |
# File 'lib/pbcore/element.rb', line 81 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.
76 77 78 79 |
# File 'lib/pbcore/element.rb', line 76 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 |
.collection_element_config ⇒ Object
Returns the SAXMachine::SaxConfig::ElementConfig that allow for multiple instances of other elements, i.e. “collection” elements which is not to be confused with <pbcoreCollection>.
103 104 105 106 107 |
# File 'lib/pbcore/element.rb', line 103 def collection_element_config sax_config.collection_elements.reject do |element_config| element_config.instance_variable_get(:@as) == :value end end |
.has_a_value? ⇒ Boolean
Returns true if the element is configured to contain a value.
86 87 88 |
# File 'lib/pbcore/element.rb', line 86 def has_a_value? !sax_config.top_level_element_value.nil? end |
.has_sax_machine_attribute?(name, opts = {}) ⇒ Boolean
115 116 117 118 119 120 121 |
# File 'lib/pbcore/element.rb', line 115 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
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/pbcore/element.rb', line 139 def has_sax_machine_collection_element?(name, opts={}) # NOTE: Accessing #collection_elements with square 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
127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/pbcore/element.rb', line 127 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| # This is a quirk of SAXMachine: when you declare a top-level # element with the .element class method, it takes your :class # option and puts it into an instance var called @data_class. key = :data_class if key == :class val == element_config.instance_variable_get("@#{key}".to_sym) end end end |
.has_sax_machine_value_element? ⇒ Boolean
123 124 125 |
# File 'lib/pbcore/element.rb', line 123 def has_sax_machine_value_element? !sax_config.top_level_element_value.empty? end |
.top_level_element_config ⇒ Object
Returns the SAXMachine::SaxConfig::ElementConfig instances that allow for a single instance of another element.
92 93 94 95 96 97 98 |
# File 'lib/pbcore/element.rb', line 92 def top_level_element_config 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 |
Instance Method Details
#attributes(key_by_xml_name: false) ⇒ Object
Returns a hash of attrubutes as the should appear in the XML.
42 43 44 45 46 47 48 49 50 51 |
# File 'lib/pbcore/element.rb', line 42 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.
56 57 58 59 60 61 62 |
# File 'lib/pbcore/element.rb', line 56 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.
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/pbcore/element.rb', line 20 def elements(key_by_xml_name: false) key_value_pairs_array = self.class.all_element_config.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.
66 67 68 |
# File 'lib/pbcore/element.rb', line 66 def to_xml build.to_xml end |
#xml_attributes ⇒ Object
Shortcut for getting xml attributes.
39 |
# File 'lib/pbcore/element.rb', line 39 def xml_attributes; attributes(key_by_xml_name: true); end |