2014-09-22 47 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表示結束(字符串,而不是一行)。雖然他們可能不需要,考慮到列表已經在內部運行,所以在每個節點上應該只剩下一個開始和結束標記。