英文:
Parse multiple XML Tags in Go
问题
我正在尝试解析一个包含以下输出的 sslscan 的 xml 文件。我想用 Go 来解析它。
<document title="SSLScan Results">
<ssltest host="x.x.x.x" port="443">
<cipher status="accepted" sslversion="TLSv1.0" bits="256" cipher="DHE-RSA-CAMELLIA256-SHA" dhebits="2048" />
.
.
<cipher status="accepted" sslversion="TLSv1.2" bits="112" cipher="DES-CBC3-SHA" /> .
<certificate>
<not-valid-before>Jun 6 00:00:00 2014 GMT</not-valid-before>
<not-valid-after>Jul 4 23:59:59 2017 GMT</not-valid-after>
</certificate>
</ssltest>
</document>
代码:
type XMLStrap struct {
Status string `xml:"status,attr"`
SSLversion string `xml:"sslversion,attr"`
Bits string `xml:"bits,attr"`
Cipher string `xml:"cipher,attr"`
}
type XMLStraps struct {
XMLName xml.Name `xml:"document"`
Straps []XMLStrap `xml:"ssltest>cipher"`
}
func ReadStraps(reader io.Reader) ([]XMLStrap, error) {
var xmlStraps XMLStraps
if err := xml.NewDecoder(reader).Decode(&xmlStraps); err != nil {
return nil, err
}
return xmlStraps.Straps, nil
}
func main() {
strapsFilePath, err := filepath.Abs("straps.xml")
if err != nil {
fmt.Println(err)
os.Exit(1)
}
file, err := os.Open(strapsFilePath)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
defer file.Close()
xmlStraps, err := ReadStraps(file)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
for i := 0; i < len(xmlStraps); i++ {
fmt.Printf("%s %s %s %s\n", xmlStraps[i].Status, xmlStraps[i].SSLversion, xmlStraps[i].Bits, xmlStraps[i].Cipher)
}
}
一切都正常工作,但我不知道如何解析 <certificate><not-valid-before>
中的日期,而不创建一个新的 reader。我尝试将前两个结构体更改为:
type XMLStrap struct {
Status string `xml:"cipher>status,attr"`
SSLversion string `xml:"cipher>sslversion,attr"`
Bits string `xml:"cipher>bits,attr"`
Cipher string `xml:"cipher>cipher,attr"`
Cert string `xml:"certificate>not-valid-after,chardata"`
}
type XMLStraps struct {
XMLName xml.Name `xml:"document"`
Straps []XMLStrap `xml:"ssltest"`
}
但这样不起作用。
xml: cipher>status chain not valid with attr flag exit status 1
显然,在较旧的 Go 版本中,它是可以工作的。
英文:
I'm trying to parse an xml file for sslscan which has the following output (shortened).
I want to parse it with Go.
<document title="SSLScan Results">
<ssltest host="x.x.x.x" port="443">
<cipher status="accepted" sslversion="TLSv1.0" bits="256" cipher="DHE-RSA-CAMELLIA256-SHA" dhebits="2048" />
.
.
<cipher status="accepted" sslversion="TLSv1.2" bits="112" cipher="DES-CBC3-SHA" /> .
<certificate>
<not-valid-before>Jun 6 00:00:00 2014 GMT</not-valid-before>
<not-valid-after>Jul 4 23:59:59 2017 GMT</not-valid-after>
</certificate>
</ssltest>
</document>
Code:
type XMLStrap struct {
Status string `xml:"status,attr"`
SSLversion string `xml:"sslversion,attr"`
Bits string `xml:"bits,attr"`
Cipher string `xml:"cipher,attr"`
}
type XMLStraps struct {
XMLName xml.Name `xml:"document"`
Straps []XMLStrap `xml:"ssltest>cipher"`
}
func ReadStraps(reader io.Reader) ([]XMLStrap, error) {
var xmlStraps XMLStraps
if err := xml.NewDecoder(reader).Decode(&xmlStraps); err != nil {
return nil, err
}
return xmlStraps.Straps, nil
}
func main() {
strapsFilePath, err := filepath.Abs("straps.xml")
if err != nil {
fmt.Println(err)
os.Exit(1)
}
file, err := os.Open(strapsFilePath)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
defer file.Close()
xmlStraps, err := ReadStraps(file)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
for i := 0; i < len(xmlStraps); i++ {
fmt.Printf("%s %s %s %s\n", xmlStraps[i].Status, xmlStraps[i].SSLversion, xmlStraps[i].Bits, xmlStraps[i].Cipher)
}
}
Everything works fine but I have no idea how to parse the date in <certificate><not-valid-before>
without creating a new reader?
I tried to change the first two structs to
type XMLStrap struct {
Status string `xml:"cipher>status,attr"`
SSLversion string `xml:"cipher>sslversion,attr"`
Bits string `xml:"cipher>bits,attr"`
Cipher string `xml:"cipher>cipher,attr"`
Cert string `xml:"certificate>not-valid-after,chardata"`
}
type XMLStraps struct {
XMLName xml.Name `xml:"document"`
Straps []XMLStrap `xml:"ssltest"`
}
but this doesn't work.
xml: cipher>status chain not valid with attr flag
exit status 1
Apparently in older versions of Go it worked.
答案1
得分: 0
我不是代码翻译器,但我可以帮你理解这段代码的含义。这段代码定义了一些结构体类型,并实现了一个函数。下面是代码的翻译:
type XMLStrap struct {
Status string `xml:"status,attr"`
SSLversion string `xml:"sslversion,attr"`
Bits string `xml:"bits,attr"`
Cipher string `xml:"cipher,attr"`
Valid string ""
}
type Certs struct {
Cert string `xml:"not-valid-after"`
}
type XMLStraps struct {
XMLName xml.Name `xml:"document"`
Straps []XMLStrap `xml:"ssltest>cipher"`
Validation Certs `xml:"ssltest>certificate"`
}
func ReadStraps(reader io.Reader) ([]XMLStrap, error) {
var xmlStraps XMLStraps
if err := xml.NewDecoder(reader).Decode(&xmlStraps); err != nil {
return nil, err
}
xmlStraps.Straps[0].Valid = xmlStraps.Validation.Cert
return xmlStraps.Straps, nil
}
这段代码定义了三个结构体类型:XMLStrap
、Certs
和XMLStraps
。XMLStrap
结构体有五个字段,分别是Status
、SSLversion
、Bits
、Cipher
和Valid
。Certs
结构体只有一个字段Cert
。XMLStraps
结构体包含了一个XMLName
字段和两个嵌套的结构体字段Straps
和Validation
。
ReadStraps
函数接收一个io.Reader
类型的参数,并返回一个[]XMLStrap
类型的切片和一个错误。函数内部首先创建了一个XMLStraps
类型的变量xmlStraps
,然后使用xml.NewDecoder(reader).Decode(&xmlStraps)
将输入的XML数据解码到xmlStraps
变量中。最后,将xmlStraps.Validation.Cert
赋值给xmlStraps.Straps[0].Valid
,并返回xmlStraps.Straps
切片和一个可能发生的错误。
希望这能帮到你!如果你有任何其他问题,请随时问我。
英文:
I had to allocate the parameter of a new object to the object which was returned. I tried this before but I did a mistake
type XMLStrap struct {
Status string `xml:"status,attr"`
SSLversion string `xml:"sslversion,attr"`
Bits string `xml:"bits,attr"`
Cipher string `xml:"cipher,attr"`
Valid string ""
}
type Certs struct {
Cert string `xml:"not-valid-after"`
}
type XMLStraps struct {
XMLName xml.Name `xml:"document"`
Straps []XMLStrap `xml:"ssltest>cipher"`
Validation Certs `xml:"ssltest>certificate"`
}
func ReadStraps(reader io.Reader) ([]XMLStrap, error) {
var xmlStraps XMLStraps
if err := xml.NewDecoder(reader).Decode(&xmlStraps); err != nil {
return nil, err
}
xmlStraps.Straps[0].Valid = xmlStraps.Validation.Cert
return xmlStraps.Straps, nil
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论