Я использую nokogiri для разбора файла XML. Некоторые из узлов в файле имеют атрибуты, специфичные для пространств имен:
<metadata xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf">
<dc:identifier id="iden" opf:scheme="ISBN">xxxx</dc:identifier>
<dc:creator opf:role="aut" opf:file-as="Name">xxxx</dc:creator>
<dc:date opf:event="publication">xxxx</dc:date>
<dc:publisher>xxxx</dc:publisher>
<meta name="cover" content="x"/>
</metadata>
Я пытаюсь удалить любой атрибут с префиксом "opf". Я сталкивался с решениями xpath в поиске атрибута значение на основе частичного совпадения, но как быть с частичным совпадением самого имени атрибута? Я перепробовал много вещей, которые не сработали. Я сделал простую вещь, чтобы попытаться извлечь имена атрибутов хотя бы, но если я это сделаю:
elements = @doc.at_xpath('//xmlns:metadata').children
elements.each { |el|
el.attributes.each { |attribute|
if attribute[1].namespace_scopes[1].prefix == "opf"
puts attribute[0]
end
}
}
Я получаю:
id
scheme
role
file-as
event
name
content
но мне нужны только те, с префиксом "opf" ("opf: схема", "opf: роль," opf: файл-как "," opf: событие "), чтобы их можно было удалить, не касаясь любой из других атрибутов. Я даже пытался форсировать его, жестко кодируя атрибуты, которые, как я знал, существовали:
opf_attributes = ["opf:file-as","opf:scheme","opf:role","opf:event"]
elements.each { |el|
opf_attributes.each { |x|
el.remove_attribute(x) if el[x] != nil
}
}
что не самый умный способ сделать это, но это все равно не сработало. С узлами ничего не происходит, а атрибуты остаются такими, какими они были. (Я не знаю, стоит ли это отмечать, но если вместо этого я использую метод remove_attr(x)
, я получаю эту ошибку: undefined method 'remove_attr' for #<Nokogiri::XML::Element:0x...>
Итак, мой вопрос:
Есть ли более понятный способ
- найти атрибуты на основе частичного совпадения и / или префикса пространства имен, затем
- удалить эти атрибуты из узлов, которые их содержат?