starting to clean things up to read real xmp files
This commit is contained in:
parent
b374a40752
commit
8f9141bece
7
bin/avm2avm
Executable file
7
bin/avm2avm
Executable file
@ -0,0 +1,7 @@
|
|||||||
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
|
require 'thor'
|
||||||
|
require 'avm/cli'
|
||||||
|
|
||||||
|
AVM::CLI.start
|
||||||
|
|
17
lib/avm/cli.rb
Normal file
17
lib/avm/cli.rb
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
require 'thor'
|
||||||
|
require 'avm/image'
|
||||||
|
require 'pp'
|
||||||
|
|
||||||
|
module AVM
|
||||||
|
class CLI < ::Thor
|
||||||
|
default_task :convert
|
||||||
|
|
||||||
|
desc 'convert', "Convert a file from one format to another"
|
||||||
|
def convert
|
||||||
|
data = $stdin.read
|
||||||
|
|
||||||
|
pp AVM::Image.from_xml(data).to_h
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -75,12 +75,12 @@ module AVM
|
|||||||
def from_xml(image, document)
|
def from_xml(image, document)
|
||||||
contacts = []
|
contacts = []
|
||||||
document.get_refs do |refs|
|
document.get_refs do |refs|
|
||||||
refs[:dublin_core].search('.//rdf:li').each do |name|
|
refs[:dublin_core].search('.//dc:creator//rdf:li').each do |name|
|
||||||
contacts << { :name => name.text }
|
contacts << { :name => name.text.strip }
|
||||||
end
|
end
|
||||||
|
|
||||||
IPTC_MULTI_FIELD_MAP.each do |key, element_name|
|
IPTC_MULTI_FIELD_MAP.each do |key, element_name|
|
||||||
if node = refs[:iptc].at_xpath("//Iptc4xmpCore:#{element_name}")
|
if node = refs[:iptc].at_xpath(".//Iptc4xmpCore:#{element_name}")
|
||||||
node.text.split(',').collect(&:strip).each_with_index do |value, index|
|
node.text.split(',').collect(&:strip).each_with_index do |value, index|
|
||||||
contacts[index][key] = value
|
contacts[index][key] = value
|
||||||
end
|
end
|
||||||
|
@ -11,12 +11,16 @@ module AVM
|
|||||||
class Image
|
class Image
|
||||||
DUBLIN_CORE_FIELDS = [ :title, :description ]
|
DUBLIN_CORE_FIELDS = [ :title, :description ]
|
||||||
|
|
||||||
|
PHOTOSHOP_SINGLES = {
|
||||||
|
'Headline' => :headline,
|
||||||
|
'DateCreated' => :date
|
||||||
|
}
|
||||||
|
|
||||||
AVM_SINGLE_FIELDS = [
|
AVM_SINGLE_FIELDS = [
|
||||||
'Distance.Notes',
|
'Distance.Notes',
|
||||||
'Spectral.Notes',
|
'Spectral.Notes',
|
||||||
'ReferenceURL',
|
'ReferenceURL',
|
||||||
'Credit',
|
'Credit',
|
||||||
'Date',
|
|
||||||
'ID',
|
'ID',
|
||||||
'Type',
|
'Type',
|
||||||
'Image.ProductQuality',
|
'Image.ProductQuality',
|
||||||
@ -40,7 +44,6 @@ module AVM
|
|||||||
:spectral_notes,
|
:spectral_notes,
|
||||||
:reference_url,
|
:reference_url,
|
||||||
:credit,
|
:credit,
|
||||||
:date,
|
|
||||||
:id,
|
:id,
|
||||||
:type,
|
:type,
|
||||||
:quality,
|
:quality,
|
||||||
@ -64,7 +67,6 @@ module AVM
|
|||||||
:spectral_notes,
|
:spectral_notes,
|
||||||
:reference_url,
|
:reference_url,
|
||||||
:credit,
|
:credit,
|
||||||
:string_date,
|
|
||||||
:id,
|
:id,
|
||||||
:image_type,
|
:image_type,
|
||||||
:image_quality,
|
:image_quality,
|
||||||
@ -141,6 +143,7 @@ module AVM
|
|||||||
end
|
end
|
||||||
|
|
||||||
refs[:photoshop].add_child(%{<photoshop:Headline>#{headline}</photoshop:Headline>})
|
refs[:photoshop].add_child(%{<photoshop:Headline>#{headline}</photoshop:Headline>})
|
||||||
|
refs[:photoshop].add_child(%{<photoshop:DateCreated>#{string_date}</photoshop:DateCreated>})
|
||||||
|
|
||||||
AVM_SINGLES_FOR_MESSAGES.each do |tag, message|
|
AVM_SINGLES_FOR_MESSAGES.each do |tag, message|
|
||||||
if value = send(message)
|
if value = send(message)
|
||||||
@ -229,14 +232,18 @@ module AVM
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if node = refs[:photoshop].at_xpath('./photoshop:Headline')
|
PHOTOSHOP_SINGLES.each do |tag, field|
|
||||||
options[:headline] = node.text
|
if node = refs[:photoshop].at_xpath("./photoshop:#{tag}")
|
||||||
|
options[field] = node.text
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if node = refs[:avm].at_xpath('./avm:Distance')
|
if node = refs[:avm].at_xpath('./avm:Distance')
|
||||||
list_values = node.search('.//rdf:li').collect { |li| li.text }
|
list_values = node.search('.//rdf:li').collect { |li| li.text }
|
||||||
|
|
||||||
case list_values.length
|
case list_values.length
|
||||||
|
when 0
|
||||||
|
options[:light_years] = node.text
|
||||||
when 1
|
when 1
|
||||||
options[:light_years] = list_values.first
|
options[:light_years] = list_values.first
|
||||||
when 2
|
when 2
|
||||||
|
27
lib/avm/node.rb
Normal file
27
lib/avm/node.rb
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
require 'delegate'
|
||||||
|
|
||||||
|
module AVM
|
||||||
|
class Node < DelegateClass(Nokogiri::XML::Node)
|
||||||
|
def initialize(xmp, node)
|
||||||
|
@xmp, @node = xmp, node
|
||||||
|
super(@node)
|
||||||
|
end
|
||||||
|
|
||||||
|
def at_xpath(path)
|
||||||
|
if node = @node.at_xpath(path, @xmp.namespaces)
|
||||||
|
self.class.new(@xmp, node)
|
||||||
|
else
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def search(path)
|
||||||
|
self.class.from_nodeset(@xmp, @node.search(path, @xmp.namespaces))
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.from_nodeset(xmp, nodeset)
|
||||||
|
nodeset.collect { |node| new(xmp, node) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -1,4 +1,5 @@
|
|||||||
require 'nokogiri'
|
require 'nokogiri'
|
||||||
|
require 'avm/node'
|
||||||
|
|
||||||
module AVM
|
module AVM
|
||||||
class XMP
|
class XMP
|
||||||
@ -9,6 +10,15 @@ module AVM
|
|||||||
'avm' => 'AVM'
|
'avm' => 'AVM'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
REQUIRED_NAMESPACES = {
|
||||||
|
:x => "adobe:ns:meta/",
|
||||||
|
:rdf => "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
|
||||||
|
:dc => "http://purl.org/dc/elements/1.1/",
|
||||||
|
:photoshop => "http://ns.adobe.com/photoshop/1.0/",
|
||||||
|
:avm => "http://www.communicatingastronomy.org/avm/1.0/",
|
||||||
|
:Iptc4xmpCore => "http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/"
|
||||||
|
}
|
||||||
|
|
||||||
attr_reader :doc
|
attr_reader :doc
|
||||||
|
|
||||||
def initialize(doc = nil)
|
def initialize(doc = nil)
|
||||||
@ -25,37 +35,73 @@ module AVM
|
|||||||
new(Nokogiri::XML(string))
|
new(Nokogiri::XML(string))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def ensure_xmlns(string)
|
||||||
|
string.gsub(%r{([</@])(\w+):}) { |all, matches| $1 + (prefix_map[$2] || $2) + ':' }
|
||||||
|
end
|
||||||
|
|
||||||
|
alias :% :ensure_xmlns
|
||||||
|
|
||||||
|
def ensure_xpath(path)
|
||||||
|
[ ensure_xmlns(path), namespaces ]
|
||||||
|
end
|
||||||
|
|
||||||
|
def search(path, node = doc)
|
||||||
|
node.search(*ensure_xpath(path))
|
||||||
|
end
|
||||||
|
|
||||||
|
def at_xpath(path, node = doc)
|
||||||
|
node.at_xpath(*ensure_xpath(path))
|
||||||
|
end
|
||||||
|
|
||||||
|
def namespaces
|
||||||
|
@namespaces ||= doc.document.collect_namespaces
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
def prefix_map
|
||||||
|
@prefix_map ||= Hash[doc.document.collect_namespaces.collect { |prefix, namespace|
|
||||||
|
prefix = prefix.gsub('xmlns:', '')
|
||||||
|
result = nil
|
||||||
|
|
||||||
|
REQUIRED_NAMESPACES.each do |original_prefix, target_namespace|
|
||||||
|
result = [ original_prefix.to_s, prefix ] if namespace == target_namespace
|
||||||
|
end
|
||||||
|
result
|
||||||
|
}.compact]
|
||||||
|
end
|
||||||
|
|
||||||
def ensure_namespaces!
|
def ensure_namespaces!
|
||||||
{
|
existing = doc.document.collect_namespaces
|
||||||
:x => "adobe:ns:meta/",
|
|
||||||
:rdf => "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
|
REQUIRED_NAMESPACES.each do |namespace, url|
|
||||||
:dc => "http://purl.org/dc/elements/1.1/",
|
doc.root.add_namespace_definition(namespace.to_s, url) if !existing.values.include?(url)
|
||||||
:photoshop => "http://ns.adobe.com/photoshop/1.0/",
|
|
||||||
:avm => "http://www.communicatingastronomy.org/avm/1.0/",
|
|
||||||
:Iptc4xmpCore => "http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/"
|
|
||||||
}.each do |namespace, url|
|
|
||||||
doc.root.add_namespace_definition(namespace.to_s, url)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def ensure_descriptions_findable!
|
def ensure_descriptions_findable!
|
||||||
added = []
|
added = []
|
||||||
|
|
||||||
doc.search('//rdf:Description').each do |description|
|
search('//rdf:Description').each do |description|
|
||||||
if first_child = description.first_element_child
|
if first_child = description.first_element_child
|
||||||
if first_child.namespace
|
if first_child.namespace
|
||||||
prefix = first_child.namespace.prefix
|
prefix = first_child.namespace.prefix
|
||||||
|
|
||||||
description['rdf:about'] = PREFIXES[prefix]
|
if prefix_description = PREFIXES[prefix_map.index(prefix)]
|
||||||
|
description[self % 'rdf:about'] = prefix_description
|
||||||
added << prefix
|
added << prefix
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if !at_xpath('//rdf:RDF')
|
||||||
|
doc.first_element_child.add_child(self % '<rdf:RDF />')
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
PREFIXES.each do |prefix, about|
|
PREFIXES.each do |prefix, about|
|
||||||
if !added.include?(prefix)
|
if !added.include?(prefix)
|
||||||
doc.at_xpath('//rdf:RDF').add_child(%{<rdf:Description rdf:about="#{about}" />})
|
at_xpath('//rdf:RDF').add_child(self % %{<rdf:Description rdf:about="#{about}" />})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -77,7 +123,7 @@ module AVM
|
|||||||
end
|
end
|
||||||
|
|
||||||
def at_rdf_description(about)
|
def at_rdf_description(about)
|
||||||
@doc.at_xpath(%{//rdf:Description[@rdf:about="#{about}"]})
|
AVM::Node.new(self, at_xpath(%{//rdf:Description[@rdf:about="#{about}"]}))
|
||||||
end
|
end
|
||||||
|
|
||||||
def empty_xml_doc
|
def empty_xml_doc
|
||||||
|
@ -23,4 +23,5 @@ Gem::Specification.new do |s|
|
|||||||
s.add_development_dependency 'mocha'
|
s.add_development_dependency 'mocha'
|
||||||
|
|
||||||
s.add_dependency 'nokogiri'
|
s.add_dependency 'nokogiri'
|
||||||
|
s.add_dependency 'thor'
|
||||||
end
|
end
|
||||||
|
0
spec/avm/cli_spec.rb
Normal file
0
spec/avm/cli_spec.rb
Normal file
@ -157,6 +157,15 @@ describe AVM::Image do
|
|||||||
end
|
end
|
||||||
|
|
||||||
context "image in it" do
|
context "image in it" do
|
||||||
|
context 'distance as a single value, assume light years' do
|
||||||
|
let(:file_path) { 'spec/sample_files/image/single_value_light_years.xmp' }
|
||||||
|
|
||||||
|
has_most_options
|
||||||
|
|
||||||
|
its(:redshift) { should be_nil }
|
||||||
|
its(:light_years) { should == light_years }
|
||||||
|
end
|
||||||
|
|
||||||
context "distance in light years" do
|
context "distance in light years" do
|
||||||
let(:file_path) { 'spec/sample_files/image/light_years.xmp' }
|
let(:file_path) { 'spec/sample_files/image/light_years.xmp' }
|
||||||
|
|
||||||
@ -197,7 +206,7 @@ describe AVM::Image do
|
|||||||
it "should have basic tags" do
|
it "should have basic tags" do
|
||||||
xml.at_xpath('//rdf:RDF').should_not be_nil
|
xml.at_xpath('//rdf:RDF').should_not be_nil
|
||||||
xml.search('//rdf:RDF/rdf:Description').should_not be_empty
|
xml.search('//rdf:RDF/rdf:Description').should_not be_empty
|
||||||
avm.at_xpath('./avm:Date').should be_nil
|
photoshop.at_xpath('./photoshop:DateCreated').should_not be_nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -221,7 +230,7 @@ describe AVM::Image do
|
|||||||
xpath_text(avm, './avm:Spectral.Notes').should == spectral_notes
|
xpath_text(avm, './avm:Spectral.Notes').should == spectral_notes
|
||||||
xpath_text(avm, './avm:ReferenceURL').should == reference_url
|
xpath_text(avm, './avm:ReferenceURL').should == reference_url
|
||||||
xpath_text(avm, './avm:Credit').should == credit
|
xpath_text(avm, './avm:Credit').should == credit
|
||||||
xpath_text(avm, './avm:Date').should == date
|
xpath_text(photoshop, './photoshop:DateCreated').should == date
|
||||||
xpath_text(avm, './avm:ID').should == id
|
xpath_text(avm, './avm:ID').should == id
|
||||||
xpath_text(avm, './avm:Type').should == type
|
xpath_text(avm, './avm:Type').should == type
|
||||||
xpath_text(avm, './avm:Image.ProductQuality').should == image_quality
|
xpath_text(avm, './avm:Image.ProductQuality').should == image_quality
|
||||||
|
@ -24,13 +24,65 @@ describe AVM::XMP do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '.from_string' do
|
describe 'xml from string' do
|
||||||
let(:xmp) { self.class.describes.from_string(string) }
|
let(:xmp) { self.class.describes.from_string(string) }
|
||||||
|
let(:doc) { xmp.doc }
|
||||||
|
|
||||||
|
describe '.from_string' do
|
||||||
let(:string) { '<xml xmlns:rdf="cats"><rdf:RDF><node /></rdf:RDF></xml>' }
|
let(:string) { '<xml xmlns:rdf="cats"><rdf:RDF><node /></rdf:RDF></xml>' }
|
||||||
|
|
||||||
specify { xmp.doc.at_xpath('//node').should_not be_nil }
|
specify { xmp.doc.at_xpath('//node').should_not be_nil }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '#ensure_namespaces! and #ensure_xmlns' do
|
||||||
|
let(:rdf_namespace) { AVM::XMP::REQUIRED_NAMESPACES[:rdf] }
|
||||||
|
|
||||||
|
def self.all_default_namespaces
|
||||||
|
it "should have all the namespaces with the default prefixes" do
|
||||||
|
namespaces = doc.document.collect_namespaces
|
||||||
|
|
||||||
|
namespaces_to_test = AVM::XMP::REQUIRED_NAMESPACES.dup
|
||||||
|
yield namespaces_to_test if block_given?
|
||||||
|
|
||||||
|
namespaces_to_test.each do |prefix, namespace|
|
||||||
|
if namespace
|
||||||
|
namespaces["xmlns:#{prefix}"].should == namespace
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
before { doc }
|
||||||
|
|
||||||
|
context 'none of the namespaces exist' do
|
||||||
|
let(:string) { '<xml><node /></xml>' }
|
||||||
|
|
||||||
|
all_default_namespaces
|
||||||
|
|
||||||
|
specify { xmp.ensure_xmlns('.//rdf:what').should == './/rdf:what' }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'one namespace exists with the same prefix' do
|
||||||
|
let(:string) { %{<xml xmlns:rdf="#{rdf_namespace}"><node /></xml>} }
|
||||||
|
|
||||||
|
all_default_namespaces
|
||||||
|
|
||||||
|
specify { xmp.ensure_xmlns('.//rdf:what').should == './/rdf:what' }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'one namespace exists with a different prefix' do
|
||||||
|
let(:string) { %{<xml xmlns:r="#{rdf_namespace}"><node /></xml>} }
|
||||||
|
|
||||||
|
all_default_namespaces { |namespaces|
|
||||||
|
namespaces.delete(:rdf)
|
||||||
|
namespaces[:r] = AVM::XMP::REQUIRED_NAMESPACES[:rdf]
|
||||||
|
}
|
||||||
|
|
||||||
|
specify { xmp.ensure_xmlns('.//rdf:what').should == './/r:what' }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe '#ensure_descriptions_findable!' do
|
describe '#ensure_descriptions_findable!' do
|
||||||
let(:document) { <<-XML }
|
let(:document) { <<-XML }
|
||||||
<x:xmpmeta xmlns:x="adobe:ns:meta/">
|
<x:xmpmeta xmlns:x="adobe:ns:meta/">
|
||||||
@ -46,7 +98,7 @@ describe AVM::XMP do
|
|||||||
let(:content) { '' }
|
let(:content) { '' }
|
||||||
|
|
||||||
[ 'Dublin Core', 'IPTC', 'Photoshop', 'AVM' ].each do |which|
|
[ 'Dublin Core', 'IPTC', 'Photoshop', 'AVM' ].each do |which|
|
||||||
specify { xmp.doc.at_xpath(%{//rdf:Description[@rdf:about="#{which}"]}).children.should be_empty }
|
specify { xmp.at_xpath(%{//rdf:Description[@rdf:about="#{which}"]}).children.should be_empty }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -67,8 +119,28 @@ describe AVM::XMP do
|
|||||||
XML
|
XML
|
||||||
|
|
||||||
[ 'Dublin Core', 'IPTC', 'Photoshop', 'AVM' ].each do |which|
|
[ 'Dublin Core', 'IPTC', 'Photoshop', 'AVM' ].each do |which|
|
||||||
specify { xmp.doc.at_xpath(%{//rdf:Description[@rdf:about="#{which}"]}).should_not be_nil }
|
specify { xmp.at_xpath(%{//rdf:Description[@rdf:about="#{which}"]}).should_not be_nil }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'has a namespace it should know about with a different prefix' do
|
||||||
|
let(:content) { <<-XML }
|
||||||
|
<rdf:Description rdf:about="" xmlns:whatever="http://purl.org/dc/elements/1.1/">
|
||||||
|
<whatever:creator />
|
||||||
|
</rdf:Description>
|
||||||
|
XML
|
||||||
|
|
||||||
|
specify { xmp.at_xpath(%{//rdf:Description[@rdf:about="Dublin Core"]}).should_not be_nil }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'has a namespace it knows nothing about' do
|
||||||
|
let(:content) { <<-XML }
|
||||||
|
<rdf:Description rdf:about="" xmlns:whatever="http://example.com">
|
||||||
|
<whatever:creator />
|
||||||
|
</rdf:Description>
|
||||||
|
XML
|
||||||
|
|
||||||
|
it { expect { xmp }.to_not raise_error }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -5,6 +5,11 @@
|
|||||||
<dc:creator>
|
<dc:creator>
|
||||||
<rdf:Seq><rdf:li>John Bintz</rdf:li></rdf:Seq>
|
<rdf:Seq><rdf:li>John Bintz</rdf:li></rdf:Seq>
|
||||||
</dc:creator>
|
</dc:creator>
|
||||||
|
<dc:title>
|
||||||
|
<rdf:Alt>
|
||||||
|
<rdf:li xml:lang="x-default">This is an image</rdf:li>
|
||||||
|
</rdf:Alt>
|
||||||
|
</dc:title>
|
||||||
</rdf:Description>
|
</rdf:Description>
|
||||||
<rdf:Description rdf:about=""
|
<rdf:Description rdf:about=""
|
||||||
xmlns:Iptc4xmpCore="http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/">
|
xmlns:Iptc4xmpCore="http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/">
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
<rdf:Description rdf:about=""
|
<rdf:Description rdf:about=""
|
||||||
xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/">
|
xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/">
|
||||||
<photoshop:Headline>Headline</photoshop:Headline>
|
<photoshop:Headline>Headline</photoshop:Headline>
|
||||||
|
<photoshop:DateCreated>2010-01-01</photoshop:DateCreated>
|
||||||
</rdf:Description>
|
</rdf:Description>
|
||||||
<rdf:Description rdf:about=""
|
<rdf:Description rdf:about=""
|
||||||
xmlns:avm="http://www.communicatingastronomy.org/avm/1.0/">
|
xmlns:avm="http://www.communicatingastronomy.org/avm/1.0/">
|
||||||
@ -29,7 +30,6 @@
|
|||||||
<avm:Distance.Notes>Distance Notes</avm:Distance.Notes>
|
<avm:Distance.Notes>Distance Notes</avm:Distance.Notes>
|
||||||
<avm:ReferenceURL>Reference URL</avm:ReferenceURL>
|
<avm:ReferenceURL>Reference URL</avm:ReferenceURL>
|
||||||
<avm:Credit>Credit</avm:Credit>
|
<avm:Credit>Credit</avm:Credit>
|
||||||
<avm:Date>2010-01-01</avm:Date>
|
|
||||||
<avm:ID>ID</avm:ID>
|
<avm:ID>ID</avm:ID>
|
||||||
<avm:Type>Observation</avm:Type>
|
<avm:Type>Observation</avm:Type>
|
||||||
<avm:Image.ProductQuality>Good</avm:Image.ProductQuality>
|
<avm:Image.ProductQuality>Good</avm:Image.ProductQuality>
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
<rdf:Description rdf:about=""
|
<rdf:Description rdf:about=""
|
||||||
xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/">
|
xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/">
|
||||||
<photoshop:Headline>Headline</photoshop:Headline>
|
<photoshop:Headline>Headline</photoshop:Headline>
|
||||||
|
<photoshop:DateCreated>2010-01-01</photoshop:DateCreated>
|
||||||
</rdf:Description>
|
</rdf:Description>
|
||||||
<rdf:Description rdf:about=""
|
<rdf:Description rdf:about=""
|
||||||
xmlns:avm="http://www.communicatingastronomy.org/avm/1.0/">
|
xmlns:avm="http://www.communicatingastronomy.org/avm/1.0/">
|
||||||
@ -28,7 +29,6 @@
|
|||||||
<avm:Distance.Notes>Distance Notes</avm:Distance.Notes>
|
<avm:Distance.Notes>Distance Notes</avm:Distance.Notes>
|
||||||
<avm:ReferenceURL>Reference URL</avm:ReferenceURL>
|
<avm:ReferenceURL>Reference URL</avm:ReferenceURL>
|
||||||
<avm:Credit>Credit</avm:Credit>
|
<avm:Credit>Credit</avm:Credit>
|
||||||
<avm:Date>2010-01-01</avm:Date>
|
|
||||||
<avm:ID>ID</avm:ID>
|
<avm:ID>ID</avm:ID>
|
||||||
<avm:Type>Observation</avm:Type>
|
<avm:Type>Observation</avm:Type>
|
||||||
<avm:Image.ProductQuality>Good</avm:Image.ProductQuality>
|
<avm:Image.ProductQuality>Good</avm:Image.ProductQuality>
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
<rdf:Description rdf:about=""
|
<rdf:Description rdf:about=""
|
||||||
xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/">
|
xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/">
|
||||||
<photoshop:Headline>Headline</photoshop:Headline>
|
<photoshop:Headline>Headline</photoshop:Headline>
|
||||||
|
<photoshop:DateCreated>2010-01-01</photoshop:DateCreated>
|
||||||
</rdf:Description>
|
</rdf:Description>
|
||||||
<rdf:Description rdf:about=""
|
<rdf:Description rdf:about=""
|
||||||
xmlns:avm="http://www.communicatingastronomy.org/avm/1.0/">
|
xmlns:avm="http://www.communicatingastronomy.org/avm/1.0/">
|
||||||
@ -29,7 +30,6 @@
|
|||||||
<avm:Distance.Notes>Distance Notes</avm:Distance.Notes>
|
<avm:Distance.Notes>Distance Notes</avm:Distance.Notes>
|
||||||
<avm:ReferenceURL>Reference URL</avm:ReferenceURL>
|
<avm:ReferenceURL>Reference URL</avm:ReferenceURL>
|
||||||
<avm:Credit>Credit</avm:Credit>
|
<avm:Credit>Credit</avm:Credit>
|
||||||
<avm:Date>2010-01-01</avm:Date>
|
|
||||||
<avm:ID>ID</avm:ID>
|
<avm:ID>ID</avm:ID>
|
||||||
<avm:Type>Observation</avm:Type>
|
<avm:Type>Observation</avm:Type>
|
||||||
<avm:Image.ProductQuality>Good</avm:Image.ProductQuality>
|
<avm:Image.ProductQuality>Good</avm:Image.ProductQuality>
|
||||||
|
77
spec/sample_files/image/single_value_light_years.xmp
Normal file
77
spec/sample_files/image/single_value_light_years.xmp
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 4.2.2-c063 53.352624, 2008/07/30-18:05:41 ">
|
||||||
|
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||||
|
<rdf:Description rdf:about=""
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||||
|
<dc:title>:
|
||||||
|
<rdf:Alt>
|
||||||
|
<rdf:li xml:lang="x-default">My title</rdf:li>
|
||||||
|
</rdf:Alt>
|
||||||
|
</dc:title>
|
||||||
|
<dc:description>
|
||||||
|
<rdf:Alt>
|
||||||
|
<rdf:li xml:lang="x-default">Description</rdf:li>
|
||||||
|
</rdf:Alt>
|
||||||
|
</dc:description>
|
||||||
|
</rdf:Description>
|
||||||
|
<rdf:Description rdf:about=""
|
||||||
|
xmlns:Iptc4xmpCore="http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/">
|
||||||
|
<Iptc4xmpCore:CreatorContactInfo rdf:parseType="Resource">
|
||||||
|
</Iptc4xmpCore:CreatorContactInfo>
|
||||||
|
</rdf:Description>
|
||||||
|
<rdf:Description rdf:about=""
|
||||||
|
xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/">
|
||||||
|
<photoshop:Headline>Headline</photoshop:Headline>
|
||||||
|
<photoshop:DateCreated>2010-01-01</photoshop:DateCreated>
|
||||||
|
</rdf:Description>
|
||||||
|
<rdf:Description rdf:about=""
|
||||||
|
xmlns:avm="http://www.communicatingastronomy.org/avm/1.0/">
|
||||||
|
<avm:Spectral.Notes>Spectral Notes</avm:Spectral.Notes>
|
||||||
|
<avm:Distance.Notes>Distance Notes</avm:Distance.Notes>
|
||||||
|
<avm:ReferenceURL>Reference URL</avm:ReferenceURL>
|
||||||
|
<avm:Credit>Credit</avm:Credit>
|
||||||
|
<avm:ID>ID</avm:ID>
|
||||||
|
<avm:Type>Observation</avm:Type>
|
||||||
|
<avm:Image.ProductQuality>Good</avm:Image.ProductQuality>
|
||||||
|
<avm:Distance>Light years</avm:Distance>
|
||||||
|
<avm:Spatial.CoordinateFrame>ICRS</avm:Spatial.CoordinateFrame>
|
||||||
|
<avm:Spatial.Equinox>100</avm:Spatial.Equinox>
|
||||||
|
<avm:Spatial.ReferenceValue>
|
||||||
|
<rdf:Seq>
|
||||||
|
<rdf:li>100</rdf:li>
|
||||||
|
<rdf:li>50</rdf:li>
|
||||||
|
</rdf:Seq>
|
||||||
|
</avm:Spatial.ReferenceValue>
|
||||||
|
<avm:Spatial.ReferenceDimension>
|
||||||
|
<rdf:Seq>
|
||||||
|
<rdf:li>200</rdf:li>
|
||||||
|
<rdf:li>150</rdf:li>
|
||||||
|
</rdf:Seq>
|
||||||
|
</avm:Spatial.ReferenceDimension>
|
||||||
|
<avm:Spatial.ReferencePixel>
|
||||||
|
<rdf:Seq>
|
||||||
|
<rdf:li>25</rdf:li>
|
||||||
|
<rdf:li>15</rdf:li>
|
||||||
|
</rdf:Seq>
|
||||||
|
</avm:Spatial.ReferencePixel>
|
||||||
|
<avm:Spatial.Scale>
|
||||||
|
<rdf:Seq>
|
||||||
|
<rdf:li>40</rdf:li>
|
||||||
|
<rdf:li>35</rdf:li>
|
||||||
|
</rdf:Seq>
|
||||||
|
</avm:Spatial.Scale>
|
||||||
|
<avm:Spatial.Rotation>10</avm:Spatial.Rotation>
|
||||||
|
<avm:Spatial.CoordsystemProjection>TAN</avm:Spatial.CoordsystemProjection>
|
||||||
|
<avm:Spatial.Quality>Full</avm:Spatial.Quality>
|
||||||
|
<avm:Spatial.Notes>Spatial Notes</avm:Spatial.Notes>
|
||||||
|
<avm:Spatial.FITSheader>FITS header</avm:Spatial.FITSheader>
|
||||||
|
<avm:Spatial.CDMatrix>
|
||||||
|
<rdf:Seq>
|
||||||
|
<rdf:li>1</rdf:li>
|
||||||
|
<rdf:li>2</rdf:li>
|
||||||
|
<rdf:li>3</rdf:li>
|
||||||
|
<rdf:li>4</rdf:li>
|
||||||
|
</rdf:Seq>
|
||||||
|
</avm:Spatial.CDMatrix>
|
||||||
|
</rdf:Description>
|
||||||
|
</rdf:RDF>
|
||||||
|
</x:xmpmeta>
|
Loading…
Reference in New Issue
Block a user