html - Golang xml解码html表

标签 html xml go xml-parsing html-parsing

我有一个简单的 HTML 表格,想要获取所有单元格的值,即使里面是 HTML 代码也是如此。

尝试使用 xml 解码,但没有获得正确的结构标记、值或属性。

import (
    "fmt"
    "encoding/xml"
)

type XMLTable struct {
XMLName xml.Name `xml:"TABLE"`
    Row []struct{
        Cell string `xml:"TD"`
    }`xml:"TR"`
}

func main() {
    raw_html_table := `
    <TABLE><TR>
    <TD>lalalal</TD>
    <TD>papapap</TD>
    <TD>fafafa</TD>
    <TD>
    <form action=\"/addedUrl/;jsessionid=KJHSDFKJLSDF293847odhf" method=POST>
    <input type=hidden name=acT value=\"Dev\">
    <input type=hidden name=acA value=\"Anyval\">
    <input type=submit name=submit value=Stop>
    </form>
    </TD>
    </TR>
    </TABLE>`

    table := XMLTable{}
    fmt.Printf("%q\n", []byte(raw_html_table)[:15])
    err := xml.Unmarshal([]byte(raw_html_table), &table)
    if err != nil {
        fmt.Printf("error: %v", err)
    }
}

作为附加信息,我不关心单元格内容,如果它是 HTML 代码(仅采用 []byte/string 值)。所以我可能会在解码之前删除单元格内容,但这种方式也不是那么容易。

我们欢迎任何关于标准 golang 库的建议。

最佳答案

坚持标准库

您的输入不是有效的 XML,因此即使您正确建模,也无法解析它。

首先,您使用的是原始 string literal将您的输入 HTML 定义为 string , 并且原始字符串文字不能包含转义符。例如这个:

<form action=\"/addedUrl/;jsessionid=KJHSDFKJLSDF293847odhf" method=POST>

您不能使用 \"在原始字符串文字中(你可以,但它会准确地表示这 2 个字符),你不必使用简单的引号:" .

接下来,在 XML 中,如果不将属性值放在引号中,则不能拥有属性。

第三,每个元素必须有一个匹配的结束元素,你的<input>元素未关闭。

例如这一行:

<input type=hidden name=acT value=\"Dev\">

必须改为:

<input type="hidden" name="acT" value="Dev" />

好的,在这些之后,输入现在是一个有效的 XML。

如何建模?就这么简单:

type XMLTable struct {
    Rows []struct {
        Cell string `xml:",innerxml"`
    } `xml:"TR>TD"`
}

以及解析和打印<TD>内容的完整代码元素:

raw_html_table := `
<TABLE><TR>
<TD>lalalal</TD>
<TD>papapap</TD>
<TD>fafafa</TD>
<TD>
<form action="/addedUrl/;jsessionid=KJHSDFKJLSDF293847odhf" method="POST">
<input type="hidden" name="acT" value="Dev" />
<input type="hidden" name="acA" value="Anyval" />
<input type="submit" name="submit" value="Stop" />
</form>
</TD>
</TR>
</TABLE>`

table := XMLTable{}
err := xml.Unmarshal([]byte(raw_html_table), &table)
if err != nil {
    fmt.Printf("error: %v\n", err)
}

fmt.Println("count:", len(table.Rows))
for _, row := range table.Rows {
    fmt.Println("TD content:", row.Cell)
}

输出(在 Go Playground 上尝试):

count: 4
TD content: lalalal
TD content: papapap
TD content: fafafa
TD content: 
    <form action="/addedUrl/;jsessionid=KJHSDFKJLSDF293847odhf" method="POST">
    <input type="hidden" name="acT" value="Dev" />
    <input type="hidden" name="acA" value="Anyval" />
    <input type="submit" name="submit" value="Stop" />
    </form>

使用合适的 HTML 解析器

如果您不能或不想更改输入的 HTML,或者您想要处理所有 HTML 输入而不仅仅是有效的 XML,您应该使用适当的 HTML 解析器而不是将输入视为 XML。

查看 https://godoc.org/golang.org/x/net/html用于符合 HTML5 的分词器和解析器。

关于html - Golang xml解码html表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44017285/

相关文章:

html - Div 与段落不一致

c# - 使用 C# 在 XML 节点内添加子节点

go - 在 Go 中作为命令启动 screen ?

inheritance - 嵌套结构 - 获取 "base"结构

go - 使用 goroutine 的多线程

javascript - 嵌入视频播放器播放按钮一次播放所有视频播放器

javascript - 同构 (SmartClient) ListGrid 不允许 Div 标签溢出(与 Twitter Bootstrap 的多选冲突)

javascript - 奇怪的是,window.document 没有返回理想情况下应该返回的正确对象。为什么?

xml - BASH SHELL SCRIPT 将一个大的 xml 文件拆分成多个小文件

java - 解析 Facebook 的 XML 查询响应问题