-1

How to run a suite of checks on an xml file? Each check is a method that returns 2 strings: it's name and pass or fail. Using xmlquery. I tried putting all the methods in an interface but can't figure out how to iterate.

In this code sample, trying to get something to work for comment "WANT":

package main

import (
        "fmt"
        "github.com/antchfx/xmlquery"
)

type node xmlquery.Node

type XmlChecks interface {
        checkUTC() (string, string)
        checkSugPresDel() (string, string)
        checkStartNum() (string, string)
        // ... there will be many
}

type XmlVerify struct {
        doc node
}

func (xver XmlVerify) checkUTC() (string, string) {
        //TBD
        return "cUTC", "pass"
}

func (xver XmlVerify) checkSugPresDel() (string, string) {
        //TBD
        return "cSugPresDel", "pass"
}

func (xver XmlVerify) checkStartNum() (string, string) {
        //TBD
        return "cStartNum", "pass"
}

func main() {
        var vrfy XmlVerify
        vrfy.doc, _ := xmlquery.Parse("myfile.xml")
        for each_method := range "all the methods in vrfy.XmlChecks" { //<--WANT
                fmt.Printf("%s %s\n", vrfy.each_method()) //<--WANT
        }

}
int
  • 91
  • 5
  • 1
    An interface just defines a method set which a value can implement. Since the methods must be statically defined in the code already, you just call those methods as needed, you don't need to "iterate" over anything. – JimB Oct 26 '21 at 17:18
  • you're saying if I have say, 1 or 2 hundred methods, then in the main function i need to call to every one of them individually, right? Since I "don't need to "iterate" over anything" – int Oct 26 '21 at 17:40
  • 2
    That number of methods is highly unusual, but if you have that many methods I assume they are being generated somehow, and the call sites could also be generated too? If you want to list methods of a type, you can certainly do that with `reflect` – JimB Oct 26 '21 at 17:51
  • good tips. thanks – int Oct 26 '21 at 21:27

1 Answers1

2

Here is an example of how you can do it with reflect. Only changed the value inside XmlVerify to make the example a bit easier. Also make sure the method names are exported (capitalize).

package main

import (
    "fmt"
    "reflect"
)

type XmlVerify struct {
    value string
}

func (xver XmlVerify) CheckUTC() (string, bool) {
    return "cUTC", xver.value == "one"
}

func (xver XmlVerify) CheckSugPresDel() (string, bool) {
    return "cSugPresDel", xver.value == "two"
}

func (xver XmlVerify) CheckStartNum() (string, bool) {
    return "cStartNum", xver.value == "three"
}

func verify(xmlverify XmlVerify) {
    t := reflect.TypeOf(xmlverify)

    for i := 0; i < t.NumMethod(); i++ {
        method := t.Method(i)
        ret := reflect.ValueOf(xmlverify).MethodByName(method.Name).Call(nil)
        fmt.Printf("%s checks passed: %t\n", ret[0], ret[1])
    }
}

func main() {
    v := XmlVerify{"two"}
    verify(v)
}

output:

cStartNum checks passed: false
cSugPresDel checks passed: true
cUTC checks passed: false
jabbson
  • 4,390
  • 1
  • 13
  • 23