如何分析 <ul> 为同级的无序列表

How to parse unorderd lists where <ul> is sibling

提问人:seanlenny 提问时间:11/15/2020 更新时间:11/15/2020 访问量:29

问:

我正在用 cheerio 解析一个 html 文件。

我卡住的部分呈现如下:

Fruit
- Banana
  - Ripe
  - Rotten
- Apple
Car

但底层 HTML 是出乎意料的

<td>
  Fruit
  <ul>
    <li>Banana</li>
    <ul>
      <li>Ripe</li>
      <li>Rotten</li>
    </ul>
    <li>Apple</li>
  </ul>
  Car
</td>

视觉上是 的子项,+ 是 的子项。但是,在底层 html 中,它们是同级的。这就是我的问题开始的地方。BananaFruitRipeRottenBanana

我的直觉是递归解析它,但是我无法弄清楚如何将“兄弟姐妹”附加为前一个节点的子节点

对上述示例的测试将期望以下输出:

[
  {
    "text": "Fruit",
    "children": [
      {
        "text": "Banana",
        "children": [
          {
            "text": "Ripe"
          },
          {
            "text": "Rotten"
          }
        ]
      },
      {
        "text": "Apple"
      }
    ]
  },
  {
    "text": "Car"
  }
]

我目前的尝试看起来像以下一些变体:

interface Note {
  text: string,
  children?: Note[]
}

function parseNote(note: cheerio.Cheerio): Note[] {
  const notes: Note[] = []
  let note: Note

  note.contents().each(function parseNoteGroups(): Note {
    const element = $(this)[0]
    // reached end of note group
    if (element.type === 'text') {
      if (note.text) {
        notes.push(note)
      }
      note = {text: $(this).text(), children: []}
    }

    if ($(this).is('li')) {
      if (children.length > 0) {
        return { text: $(this).text(), children }
      }
      return { text: $(this).text() }
    }

    if ($(this).is('ul')) {
      $(this).children().each(function () {
        children.push(parseNoteGroups.bind(this)())
      })
    }
  })

  notes.push(note) // push last note

  return notes
}

它有一些问题。但我正在努力在概念上使这项工作。感谢您的阅读,我期待任何建议或解决方案。

javascript jquery html 解析 cheerio

评论

1赞 Rory McCrossan 11/15/2020
问题是因为您的 HTML 无效。你不能有一个作为另一个人的孩子。它需要等等ulul<ul><li>Banana<ul><li>Other options....</li></ul></li></ul>
0赞 seanlenny 11/15/2020
@Rory McCrossan,我也是这么认为的。但是原始的html文件来自一个大型且经常使用的数据集。我无法更改html。如上所述,我的浏览器毫无怨言地呈现了它。
1赞 Rory McCrossan 11/15/2020
它可以正确呈现,因为大多数浏览器会为您更正 HTML,但是当您尝试使用 JS 解析结构时会出现问题 - 正如您现在发现的那样。很可能有一个 hacky 解决方案来创可贴输出,但到目前为止最好的解决方案是修复 HTML 输出,以便可以正确编写 JS。目前,如果浏览器修改了它们处理格式错误的 HTML 的方式,您的系统就会崩溃。
0赞 seanlenny 11/15/2020
@RoryMcCrossan我明白了。所以 Chrome 修复了 HTML,但没有在检查器中显示修复?

答: 暂无答案