如何从 Ruby 中的 Nokogiri 集合生成不同的 HTML 格式

How to generate a different HTML format from a Nokogiri collection in Ruby

我正在编写一个脚本,用于迁移当前 HTML 页面并将其转换为不同的 HTML 布局。我可以使用 Nokogiri 和 XPath 从文档中获取信息。

问题是如何以类似于遍历数组和散列的方式遍历通过循环检索的节点以生成我需要的布局。

这是我要转换的原始布局的示例:

<ul id="nav">
    <li><a href="somelink1.html">Link 1</a> </li>
    <li>
        <a href="#">Link 2</a>
        <ul>
            <li><a href="sublink1.html">Sublink 1</a></li>
            <li><a href="sublink2.html">Sublink 2</a></li>
        </ul>
    </li>
</ul>

这段代码是我目前试过的。问题是当它循环遍历集合集时,每次遍历集合时都会输出新 HTML 标记中的所有节点,而不是仅输出当前索引处的信息。

require 'nokogiri'
source_file = Nokogiri.XML(open("navigation.inc"))
source_file = Nokogiri.XML(source_file.to_s.encode('UTF-8', 'binary', invalid: :replace, undef: :replace, replace: ''))

navigation = ""

if source_file.xpath("//ul[@id = 'nav']").length > 0

   navcontain = source_file.xpath("//ul[@id = 'nav']/li")

   navcontain.each do | child |

   if child.xpath("//li and count(*) = 2")
        navigation = navigation + "<details>"
        child.xpath("//li/ul").each do | children |
                 navigation = navigation + child.xpath("//li/a").to_s

         end #end child loop
        navigation = navigation + "</details>"
     else
        navigation = navigation + source_file.xpath("//ul[@id = 'nav']/li/a").to_s

     end #end conditional check
   end #end initial loop
end #end length check

puts navigation

这是上面代码当前正在执行的操作的示例:

<div id="nav">
    <details>
        <a href="somelink1.html">Link 1</a>
        <a href="#">Link 2</a>
        <a href="sublink1.html">Sublink 1</a>
        <a href="sublink2.html">Sublink 2</a>
    </details>
    <details>
        <a href="somelink1.html">Link 1</a>
        <a href="#">Link 2</a>
        <a href="sublink1.html">Sublink 1</a>
        <a href="sublink2.html">Sublink 2</a>
    </details>

</div>

我想要的转换后的格式是:

<div id="nav">
    <a href="somelink1.html">Link 1</a>

    <details>
        <summary>
            Link 2
        </summary>

        <a href="sublink1.html">Sublink 1</a>
        <a href="sublink2.html">Sublink 2</a>

    </details>

</div>

我相信部分代码可以正常工作,因为我可以确定单级和二级结构的总数 link。我还没有想出如何将数据翻译成我需要的最终版本。

您发布的代码不会产生您发布的输出。代码实际上产生了这个:

<a href="somelink1.html">Link 1</a>
<a href="#">Link 2</a>
<details>
  <a href="somelink1.html">Link 1</a>
  <a href="#">Link 2</a>
  <a href="sublink1.html">Sublink 1</a>
  <a href="sublink2.html">Sublink 2</a>
</details>

我猜你不想在 <details> 部分中使用 Link 1Link 2

您使用 XPath 选择器的方式存在问题:

child.xpath("//li/ul")

搜索从文档的根开始,而不是 child 元素。相反,您需要使用:

child.xpath(".//li/ul")

如果您想从 child 元素开始搜索。

这里是经过清理的代码,应该会产生您需要的输出:

require 'nokogiri'
source_file = Nokogiri.XML(File.read("navigation.inc").encode('UTF-8', 'binary', invalid: :replace, undef: :replace, replace: ''))

navigation = ""

if source_file.xpath("//ul[@id = 'nav']").length > 0
  navcontain = source_file.xpath("//ul[@id = 'nav']/li")

  navcontain.each do |child|
    if child.xpath(".//li and count(*) = 2")
      navigation += "<details>"

      child.xpath(".//ul/li/a").each do |grandchild|
        navigation += grandchild.to_s
      end

      navigation = navigation + "</details>"
    else
      # not sure how that's supposed to work based on your input file example
       navigation = navigation + source_file.xpath("//ul[@id = 'nav']/li/a").to_s
    end
  end
end

puts navigation