Если «мусор из Excel» такой простой, а элементы ss:Type="String"
содержат только текст или бессмысленную <Font>
, тогда:
doc.encoding = 'utf-8'
doc.xpath('//Data[@Type="String"]').each { |n| n.content = n.text }
должно устранить уродство. Это дает мне такой вывод:
<?xml version="1.0" encoding="utf-8"?>
<Worksheet Name="Subtitles">
<Table ExpandedColumnCount="3" ExpandedRowCount="53" FullColumns="1" FullRows="1" DefaultRowHeight="13.5">
<Column StyleID="s62" Width="80.25" Span="1"/>
<Column Index="3" StyleID="s63" Width="249.75"/>
<Row AutoFitHeight="0">
<Cell><Data Type="String">00:00:11:09</Data></Cell>
<Cell><Data Type="String">00:00:13:06</Data></Cell>
<Cell><Data xmlns="http://www.w3.org/TR/REC-html40" Type="String">안녕하세요, 저는 잭, 9살 입니다. </Data></Cell>
</Row>
</Table>
</Worksheet>
Я не знаю, как убедить Нокогири убрать эту паузу xmlns
.
Если вы не уверены, что находится внутри <Data>
, вы можете удалить только <Font>
что-то вроде этого:
def font_killer(children)
children.each do |c|
if(c.name == 'Font')
c.replace(font_killer(c.children))
else
font_killer(c.children)
end
end
children
end
doc = Nokogiri::XML(open('junk_from_excel.xml').read)
doc.encoding = 'utf-8'
doc.xpath('//Data[@Type="String"]').each { |n| font_killer(n.children) }
Я немного проверил это, но я бы порекомендовал вам немного больше протестировать его на реальных данных.
В любом случае вы теряете префиксы пространства имен ss
и x
; это справедливо, так как XML неправильно объявляет пространства имен, поэтому Нокогири делает вид, что их не существует. Если вам нужны пространства имен, добавьте эти атрибуты
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
в элемент <Worksheet>
перед атрибутом ss:Name
, а затем обновите выражения XPath, включив в него пространство имен:
doc.xpath('//ss:Data[@ss:Type="String"]|//Data[@ss:Type="String"]')
Возможно, есть лучший способ выразить это, но мой XPath-Fu не так силен; это должно сделать работу, хотя.