2014-09-22 17 views
0

我正在写一个脚本来将模板文件转换为胡须,并且我想使用Nokogiri。但有没有办法与胡子一起使用它,特别是将标签如<tmpl_if var>转换为{{#var}}?基本上我想转换:使用Nokogiri留胡子?

<tmpl_if foo> 
    <tmpl_if bar> 
     <p>Test</p> 
    </tmpl_if> 
</tmpl_if> 

{{#foo}} 
    {{#bar}} 
     <p>Test</p> 
    {{/bar}} 
{{/foo}} 

我能得到我需要改变的节点,但我不能找到一种方法来改变仅仅是个开始和结束标记。有没有什么办法可以改变标签为字符串使用正则表达式,而不影响内部的HTML?

回答

0

你可以做这样的事情:

  • 与引入nokogiri,你改变每个tmpl_if标签这样的标签名称:<tmpl_if bar> =><tmpl_if_bar bar>。此更改的目标是在结束标记中包含属性名称。

  • 你用gsub替换所有的<tmpl_if_...>标签。

-

require 'nokogiri' 

html_doc = <<EOD 
<tmpl_if foo> 
    <tmpl_if bar> 
     <p>Test</p> 
    </tmpl_if> 
</tmpl_if> 
EOD 

doc = Nokogiri::HTML.parse(html_doc) 
attrList = doc.xpath('//tmpl_if/@*') 
attrList.each{|attr| attr.parent.name = attr.parent.name + "_" + attr.name} 
html_doc = doc.css('body').inner_html 

reps = [[/<tmpl_if_(\w+)[^>]*>/, '{{#\1}}'], [/<\/tmpl_if_(\w+)>/, '{{/\1}}']] 
reps.each {|rep| html_doc.gsub!(rep[0], rep[1])} 

puts html_doc 

这样,你避免所有的嵌套问题。

+0

我想我找到了一种不依赖于中途改变的更好方法。 – CSturgess 2014-09-23 14:23:35

+0

@CSturgess:在这种情况下,将其作为答案发布。 – 2014-09-23 14:29:45

0

我找到了一种方法,首先找到需要更改的每个节点,然后将其转换为字符串,然后在替换节点之前使用正则表达式替换(依赖于\ A和\ Z)。如果反转列表,它将首先在内部节点上运行。 ​

@doc.css("tmpl_if").reverse.each do |node| 
    str = node.to_s; 
    str.sub(/\A<tmpl_if ([^>]*)>(.*)<\/tmpl_if>\Z/m, '{{#\1}}\2{{/\1}}') 
    node.replace(str) 
end 

`

一些变化可以使这项工作对于任何/所有标签这样。 \A表示字符串的开始,\Z表示结束(字符串,而不是一行)。虽然他们可能不需要,考虑到列表已经在内部运行,所以在每个节点上应该只剩下一个开始和结束标记。