在ul和ol中解析嵌套的li

时间:2022-04-16 20:34:22

I have a scenario in which when li comes under ul I need to replace it with a dot(.) and when li comes and ol I need to replace it with a number.

我有一个场景,当li进入ul时我需要用点(。)替换它,当li来的时候我需要用数字替换它。

But the problem is-

但问题是 -

1) It is not doing for nested li

1)它不适用于嵌套的li

2) It is appending at the same level. Same level means as soon as it finds li it will first add dot(.) and then it will add number.

2)它在同一级别附加。相同级别意味着一旦找到li它将首先添加点(。)然后它将添加数字。

What I want

我想要的是

1) Whenever li comes inside ul it should add dot(.).

1)每当li进入ul时,它应该添加点(。)。

2) Whenever li comes inside ol it should add a number.

2)每当李进入ol时,它应该添加一个数字。

data = "<ol>\n<li>Introduction\n<ol>\n<li>hyy ssss</li>\n</ol>\n</li>\n<li>Description</li>\n<li>Observation</li>\n<li>Results</li>\n<li>Summary</li>\n</ol>\n<ul>\n<li>Introduction</li>\n<li>Description\n<ul>\n<li>Observation\n<ul>\n<li>Results\n<ul>\n<li>Summary</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n<li>Overview</li>\n</ul>\n<p>All the testing regarding bullet points would have been covered with the above content. Hence publishing this content will make an entry in in the selected  page, cricket page and so on.</p>\n"

    content = Nokogiri::HTML.parse(data)
    content.at('ul').children.xpath("//li").each { |li| li.inner_html="\u2022 "+li.inner_html }
    content.at('ol').children.xpath("//li").each_with_index { |li,index| li.inner_html="#{index} "+li.inner_html }

1 个解决方案

#1


1  

Perhaps you need this:

也许你需要这个:

content.css('ol').reverse.each do |ol| 
  ol.css('> li').each_with_index { |li,index| li.inner_html="#{index + 1} "+li.inner_html }
end
content.css('ul > li').reverse.each { |li| li.inner_html="\u2022 "+li.inner_html }

puts content

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body>
<ol>
  <li>1 Introduction
    <ol>
      <li>1 hyy ssss</li>
    </ol>
  </li>
  <li>2 Description</li>
  <li>3 Observation</li>
  <li>4 Results</li>
  <li>5 Summary</li>
</ol>
<ul>
  <li>• Introduction</li>
  <li>• Description
    <ul>
      <li>• Observation
        <ul>
          <li>• Results
            <ul>
              <li>• Summary</li>
            </ul>
          </li>
        </ul>
      </li>
    </ul>
  </li>
  <li>• Overview</li>
</ul>
</body></html>

Reason of doing reverse -
Consider the dom:

反向的原因 - 考虑一下dom:

<ul>
  <li>Description
    <ul>
      <li>Observation</li>
    </ul>
  </li>
</ul>

When you do content.css('ul > li'), you get in order of [description, observation]. Without reverse, when you run the snippet, you change the description, but doing so will also change the object_id of observation node. Then you changed the observation node which is not referenced anywhere in content. That's why, I reversed it and acquired children before parents. By doing this, I made sure I'm changing the child first and then changed the parent so parent was aware of the change in child and there is no unreferenced node anywhere.

当你做content.css('ul> li')时,你得到[描述,观察]的顺序。如果没有反向,当您运行代码段时,您将更改描述,但这样做也会更改观察节点的object_id。然后,您更改了内容中未引用的观察节点。这就是为什么,我在父母面前扭转了它并收养了孩子。通过这样做,我确保我先改变孩子,然后更改父母,以便父母知道孩子的变化,并且在任何地方都没有未引用的节点。

Suppose description's node id is 1234 and observation node_id is 2345. When you mutated description, it changed itself but also changed it's child(2345). New object id can be 3456 and 4567 respectively. Then you changed 2345 (by iteration), but it makes no effect because your content is showing 3456 -> 4567

假设描述的节点id是1234,观察node_id是2345.当你改变描述时,它改变了自己,但也改变了它的孩子(2345)。新对象id可以分别为3456和4567。然后你改变了2345(通过迭代),但它没有任何效果,因为你的内容显示3456 - > 4567

Hope this makes sense.

希望这是有道理的。

#1


1  

Perhaps you need this:

也许你需要这个:

content.css('ol').reverse.each do |ol| 
  ol.css('> li').each_with_index { |li,index| li.inner_html="#{index + 1} "+li.inner_html }
end
content.css('ul > li').reverse.each { |li| li.inner_html="\u2022 "+li.inner_html }

puts content

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body>
<ol>
  <li>1 Introduction
    <ol>
      <li>1 hyy ssss</li>
    </ol>
  </li>
  <li>2 Description</li>
  <li>3 Observation</li>
  <li>4 Results</li>
  <li>5 Summary</li>
</ol>
<ul>
  <li>• Introduction</li>
  <li>• Description
    <ul>
      <li>• Observation
        <ul>
          <li>• Results
            <ul>
              <li>• Summary</li>
            </ul>
          </li>
        </ul>
      </li>
    </ul>
  </li>
  <li>• Overview</li>
</ul>
</body></html>

Reason of doing reverse -
Consider the dom:

反向的原因 - 考虑一下dom:

<ul>
  <li>Description
    <ul>
      <li>Observation</li>
    </ul>
  </li>
</ul>

When you do content.css('ul > li'), you get in order of [description, observation]. Without reverse, when you run the snippet, you change the description, but doing so will also change the object_id of observation node. Then you changed the observation node which is not referenced anywhere in content. That's why, I reversed it and acquired children before parents. By doing this, I made sure I'm changing the child first and then changed the parent so parent was aware of the change in child and there is no unreferenced node anywhere.

当你做content.css('ul> li')时,你得到[描述,观察]的顺序。如果没有反向,当您运行代码段时,您将更改描述,但这样做也会更改观察节点的object_id。然后,您更改了内容中未引用的观察节点。这就是为什么,我在父母面前扭转了它并收养了孩子。通过这样做,我确保我先改变孩子,然后更改父母,以便父母知道孩子的变化,并且在任何地方都没有未引用的节点。

Suppose description's node id is 1234 and observation node_id is 2345. When you mutated description, it changed itself but also changed it's child(2345). New object id can be 3456 and 4567 respectively. Then you changed 2345 (by iteration), but it makes no effect because your content is showing 3456 -> 4567

假设描述的节点id是1234,观察node_id是2345.当你改变描述时,它改变了自己,但也改变了它的孩子(2345)。新对象id可以分别为3456和4567。然后你改变了2345(通过迭代),但它没有任何效果,因为你的内容显示3456 - > 4567

Hope this makes sense.

希望这是有道理的。