我正在尝试通过删除字体标记来清理一些xml。这就是我的开始:
<?xml version="1.0"?>
<Worksheet ss:Name="Subtitles">
<Table ss:ExpandedColumnCount="3" ss:ExpandedRowCount="53" x:FullColumns="1"
x:FullRows="1" ss:DefaultRowHeight="13.5">
<Column ss:StyleID="s62" ss:Width="80.25" ss:Span="1"/>
<Column ss:Index="3" ss:StyleID="s63" ss:Width="249.75"/>
<Row ss:AutoFitHeight="0">
<Cell><Data ss:Type="String">00:00:11:09</Data></Cell>
<Cell><Data ss:Type="String">00:00:13:06</Data></Cell>
<Cell><ss:Data ss:Type="String" xmlns="http://www.w3.org/TR/REC-html40">안녕하세요<Font
html:Face="Arial" html:Color="#000000">, </Font><Font html:Face="돋움"
html:Color="#000000">저는</Font><Font html:Face="Arial" html:Color="#000000"> </Font><Font
html:Face="돋움" html:Color="#000000">잭</Font><Font html:Face="Arial"
html:Color="#000000">, 9</Font><Font html:Face="돋움" html:Color="#000000">살</Font><Font
html:Face="Arial" html:Color="#000000"> </Font><Font html:Face="돋움"
html:Color="#000000">입니다</Font><Font html:Face="Arial" html:Color="#000000">. </Font></ss:Data></Cell>
</Row>
</Table>
</Worksheet>
</Workbook>
这就是我想要的:
<?xml version="1.0"?>
<Worksheet ss:Name="Subtitles">
<Table ss:ExpandedColumnCount="3" ss:ExpandedRowCount="53" x:FullColumns="1"
x:FullRows="1" ss:DefaultRowHeight="13.5">
<Column ss:StyleID="s62" ss:Width="80.25" ss:Span="1"/>
<Column ss:Index="3" ss:StyleID="s63" ss:Width="249.75"/>
<Row ss:AutoFitHeight="0">
<Cell><Data ss:Type="String">00:00:11:09</Data></Cell>
<Cell><Data ss:Type="String">00:00:13:06</Data></Cell>
<Cell><Data ss:Type="String">안녕하세요, 저는잭, 9살 입니다.</Data></Cell>
</Row>
</Table>
</Worksheet>
</Workbook>
我正在努力用nokogiri来实现这个目标。这是我到目前为止所得到的:
require 'nokogiri'
f = File.open("junk_from_excel.xml")
doc = Nokogiri::XML(f)
# <Font html:Face="돋움" html:Color="#000000">, </Font>
doc.xpath('//@Face').each(&:remove)
# becomes: <Font html:Color="#000000">, </Font>
doc.xpath('//@Color').each(&:remove)
# becomes: <Font>, </Font>
puts doc
我不确定这有什么用处。我仍然需要转向:
<Font>, </Font>
成:
,
非常感谢任何帮助!
答案 0 :(得分:1)
谢谢大家的帮助。我在最后得到了这个hackish gsub的东西:
require 'nokogiri'
f = File.open("full_file_from_excel.xml")
doc = Nokogiri::XML(f)
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('full_file_from_excel.xml').read)
doc.encoding = 'utf-8'
doc.xpath('//ss:Data[@ss:Type="String"]|//Data[@ss:Type="String"]').each { |n| font_killer(n.children) }
#save to file:
open('full_file_from_excel_fixed.xml', 'w') { |f|
f.puts doc
}
# few more file cleanup find and replace
text = File.read("full_file_from_excel_fixed.xml")
replace = text.gsub(" </ss:Data>","</Data>")
replace = replace.gsub(" </ss:Data>","</Data>")
replace = replace.gsub("</ss:Data>","</Data>")
replace = replace.gsub("<ss:Data xmlns=\"http://www.w3.org/TR/REC-html40\" ss:Type=\"String\">", "<Data ss:Type=\"String\">")
File.open("full_file_from_excel_fixed.xml", "w") {|file| file.puts replace}
答案 1 :(得分:0)
您可以在删除内容之前提取内容,如下所示:
doc.xpath('//*[@Face]').each do |node|
node.children.each do |child|
node.parent << child
end
node.remove
end
来源:http://rubyforge.org/pipermail/nokogiri-talk/2009-June/000333.html
答案 2 :(得分:0)
如果“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>
我不知道如何说服Nokogiri去除那个迷路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没有正确声明命名空间,因此Nokogiri假装它们不存在。如果您想要名称空间,请添加这些属性
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并不那么强大;那应该可以完成工作。