Skip to content

Instantly share code, notes, and snippets.

@gkellogg
Created October 24, 2010 06:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gkellogg/643221 to your computer and use it in GitHub Desktop.
Save gkellogg/643221 to your computer and use it in GitHub Desktop.
Code use to place XMLLiteral in canonical form and preserve @Profile, @Prefix, @vocab and @lang mappings.
# Add already mapped namespaces and language
@contents = contents.map do |c|
c = Nokogiri::XML.parse(c.copy(true).to_s) if c.is_a?(LibXML::XML::Node)
if c.is_a?(Nokogiri::XML::Element)
c = Nokogiri::XML.parse(c.dup.to_xml(:save_with => Nokogiri::XML::Node::SaveOptions::NO_EMPTY_TAGS)).root
# Gather namespaces from self and decendant nodes
#
# prefix mappings
# Look for @xmlns and @prefix mappings. Add any other mappings from options[:prefixes]
# that aren't already defined on this node
defined_mappings = {}
prefix_mappings = {}
c.traverse do |n|
ns = n.namespace
next unless ns
prefix = ns.prefix ? "xmlns:#{ns.prefix}" : "xmlns"
defined_mappings[ns.prefix.to_s] = ns.href.to_s
c[prefix] = ns.href unless c.namespaces[prefix]
end
mappings = c["prefix"].to_s.split(/\s+/)
while mappings.length > 0 do
prefix, uri = mappings.shift.downcase, mappings.shift
#puts "uri_mappings prefix #{prefix} <#{uri}>"
next unless prefix.match(/:$/)
prefix.chop!
# A Conforming RDFa Processor must ignore any definition of a mapping for the '_' prefix.
next if prefix == "_"
defined_mappings[prefix] = uri
prefix_mappings[prefix] = uri
end
# Add prefixes, being careful to honor mappings defined on the element
if options[:prefixes]
options[:prefixes].each_pair do |p, ns|
prefix_mappings[p] = ns.uri unless defined_mappings.has_key?(p)
end
if prefix_mappings.length
c["prefix"] = prefix_mappings.keys.sort.map {|p| "#{p}: #{prefix_mappings[p]}"}.join(" ")
end
end
# Add profiles, being careful to honor profiles defined on the element
if options[:profiles].is_a?(Array) && options[:profiles].length > 0
profiles = c["profile"].to_s.split(" ")
profiles += options[:profiles]
c["profile"] = profiles.join(" ")
end
# Add default vocabulary, being careful to honor any defined on the element
if options[:default_vocabulary] && !c["vocab"]
c["vocab"] = options[:default_vocabulary].to_s
end
if options[:language] && c["lang"].to_s.empty?
c["xml:lang"] = options[:language]
end
end
c.to_xml(:save_with => (Nokogiri::XML::Node::SaveOptions::NO_EMPTY_TAGS))
end.join("")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment