diff --git a/lib/nokogiri/xml/document.rb b/lib/nokogiri/xml/document.rb index 87445542fd5..9c68f2f0f32 100644 --- a/lib/nokogiri/xml/document.rb +++ b/lib/nokogiri/xml/document.rb @@ -164,6 +164,48 @@ def collect_namespaces end end + ## + # In order to collect all namespaces in a document with multiple + # default namespace definitions use + # - collect_namespaces_href_keys + # - collect_namespaces_prefix_keys + # + # See https://github.com/sparklemotion/nokogiri/issues/885 for details + # + # collect_namespaces_href_keys will return e.g. + # + # { + # "http://www.w3.org/XML/1998/namespace" => ["xml"], + # "http://www.smpte-ra.org/schemas/429-7/2006/CPL" => [nil], + # "http://isdcf.com/schemas/draft/2011/cpl-metadata" => ["meta"], + # "http://www.w3.org/2000/09/xmldsig#" => [nil] + # } + # + # where nil implies xmlns. + # + # collect_namespaces_prefix_keys will return e.g. + # + # { + # "xml" => ["http://www.w3.org/XML/1998/namespace"], + # "nil" => ["http://www.smpte-ra.org/schemas/429-7/2006/CPL", "http://www.w3.org/2000/09/xmldsig#"], + # "meta" => ["http://isdcf.com/schemas/draft/2011/cpl-metadata"] + # } + # + # where nil implies xmlns. + # + def collect_namespaces_href_keys + xpath("//namespace::*").inject({}) do |hash, ns| + (hash[ ns.href ] ||= []) << ns.prefix unless (hash[ ns.href ] and hash[ ns.href ].include? ns.prefix) + hash + end + end + def collect_namespaces_prefix_keys + xpath("//namespace::*").inject({}) do |hash, ns| + (hash[ ns.prefix ] ||= []) << ns.href unless (hash[ ns.prefix ] and hash[ ns.prefix ].include? ns.href) + hash + end + end + # Get the list of decorators given +key+ def decorators key @decorators ||= Hash.new