我有一个简单的HTML表格,并且想要获取所有单元格值,即使它是HTML代码。
尝试使用xml unmarshal,但没有获得正确的struct标签,值或属性。
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库的任何建议。
答案 0 :(得分:3)
您的输入不是有效的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输入而不仅仅是有效的XML,您应该使用正确的HTML解析器而不是将输入视为XML
查看https://godoc.org/golang.org/x/net/html以获取符合HTML5的标记器和解析器。
答案 1 :(得分:0)
一旦您的输入是有效的HTML(您的代码段在属性中缺少引号),您就可以配置xml.Decoder
实体和autoclose地图(并使其非严格),这将最终起作用:
package main
import (
"encoding/xml"
"fmt"
"strings"
)
type XMLTable struct {
Rows []struct {
Cell string `xml:",innerxml"`
} `xml:"TR>TD"`
}
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{}
decoder := xml.NewDecoder(strings.NewReader(raw_html_table))
decoder.Entity = xml.HTMLEntity
decoder.AutoClose = xml.HTMLAutoClose
decoder.Strict = false
err := decoder.Decode(&table)
if err != nil {
fmt.Printf("error: %v", err)
}
fmt.Printf("%#v\n", table)
}