Go XML - 在HTML中解析布尔属性会导致XML验证错误

时间:2015-12-22 19:44:55

标签: xml parsing go

我有一个带有以下标记的html输出。

<hr noshade>

我的结构是

type Hr struct {
    TagName xml.Name `xml:"hr"`
}

当我尝试使用&#34; encoding / xml&#34;传递html时,会抛出一个错误,说该属性没有'='个字符。

我已经看到抛出此错误,因为默认的Decoder在Strict设置为true的情况下评估XML。

如何忽略此问题并继续解析文档(使用xml.Unmarshal())?

编辑:包括XML和使用的结构。

我找到了Decoder设置,并使用了NewDecoder,但是看起来解组并没有正确发生。

<html><head><title>Some title</title></head>
<body>
 <h2>Title here</h2>
 <ul>
  <li><a href="../">..</a></li>
  <li><a href="file1.txt">file1.txt</a></li>
  <li><a href="file2.zip">file2.zip</a></li>
  .....
 </ul>
 <hr noshade><em>Powered by <a href="http://subversion.apache.org/">Apache Subversion</a> version 1.7.18 (r1615261).</em>
</body></html>

到目前为止编写的代码

type Anchor struct {
    TagName xml.Name `xml:"a"`
    Href    string   `xml:"href,attr"`
}

type ListEntry struct {
    TagName  xml.Name `xml:"li"`
    Filename Anchor
}

type DirList struct {
    XMLName xml.Name `xml:"ul"`
    Entries []ListEntry
}

type Header struct {
    TagName xml.Name `xml:"h2"`
}

type Head struct {
    TagName xml.Name `xml:"head"`
    title   Title
}

type Title struct {
    TagName xml.Name `xml:"title"`
}

type html struct {
    TagName xml.Name `xml:"html"`
    body    Body     `xml:"body"`
    head    Head
}

type Body struct {
    H2            Header
    DirectoryList DirList
    hr            Hr
    em            Em
}

type Hr struct {
    TagName xml.Name `xml:"hr"`
}

type Em struct {
    TagName xml.Name `xml:"em"`
    link    Anchor
}

   contents := retrieveFromWeb()

    htmlTag := html{}
    decoder := xml.NewDecoder(strings.NewReader(contents))
    decoder.Strict = false
    decoder.AutoClose = xml.HTMLAutoClose
    decoder.Entity = xml.HTMLEntity

    err = decoder.Decode(&htmlTag)

    fmt.Println("DirList: ", htmlTag)

当前输出

DirList:  {{ } {{{ }} {{ } []} {{ }} {{ } {{ } }}} {{ } {{ }}}}

2 个答案:

答案 0 :(得分:0)

您可以使用解码器解组。使用解码器可以关闭严格的解析并克服您所面临的错误。由于你只放了一行xml / html来解析我已经假设了根元素,hr标签和下面的一些值是示例实现

package main

import (
    "encoding/xml"
    "fmt"
    "strings"
)

type Hr struct {
    XMLName xml.Name `xml:"a"`
    TagName string   `xml:"hr"`
}

func main() {   
    s := "<a><hr noshade>value</hr></a>"

    hr := &Hr{}
    d := xml.NewDecoder(strings.NewReader(s))
    d.Strict = false
    err := d.Decode(hr)
    if err != nil {
        panic(err)
    }

    fmt.Println(hr.TagName)
}

fmt.Println(hr.TagName)将打印&#34;值&#34;

答案 1 :(得分:0)

您的代码中存在许多错误:

  • 如果该属性不是公共的,则其他包(在这种情况下为xml)无法访问它:将所有属性设置为大写。
  • li缺少标签名称。

查看此工作代码

http://play.golang.org/p/rkNf2OfvdM

package main

import (
    "encoding/xml"
    "fmt"
    "log"
    "strings"
)

type Anchor struct {
    XMLName xml.Name `xml:"a"`
    Href    string   `xml:"href,attr"`
}

type ListEntry struct {
    XMLName xml.Name `xml:"li"`
        Filename Anchor
}

type DirList struct {
    XMLName xml.Name    `xml:"ul"`
    Entries []ListEntry `xml:"li"`
}

type Header struct {
    XMLName xml.Name `xml:"h2"`
}

type Head struct {
    XMLName xml.Name `xml:"head"`
    Title   Title
}

type Title struct {
    XMLName xml.Name `xml:"title"`
}

type Html struct {
    XMLName xml.Name `xml:"html"`
    Body    Body     `xml:"body"`
    Head    Head
}

type Body struct {
    H2            Header
    DirectoryList DirList
    Hr            Hr
    Em            Em
}

type Hr struct {
    XMLName xml.Name `xml:"hr"`
}

type Em struct {
    XMLName xml.Name `xml:"em"`
    link    Anchor
}

var contents = `<html><head><title>Some title</title></head>
<body>
 <h2>Title here</h2>
 <ul>
  <li><a href="../">..</a></li>
  <li><a href="file1.txt">file1.txt</a></li>
  <li><a href="file2.zip">file2.zip</a></li>
 </ul>
 <hr noshade><em>Powered by <a href="http://subversion.apache.org/">Apache Subversion</a> version 1.7.18 (r1615261).</em>
</body></html>`

func main() {
    htmlTag := Html{}
    decoder := xml.NewDecoder(strings.NewReader(contents))
    decoder.Strict = false
    decoder.AutoClose = xml.HTMLAutoClose
    decoder.Entity = xml.HTMLEntity

    err := decoder.Decode(&htmlTag)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("DirList: %v %#[1]v\n", htmlTag)
}