dynamic xml

Sett 78 ganger
Hopp til første uleste melding

Jeffrey Smith

ulest,
18. okt. 2017, 11:50:4518.10.2017
til golang-nuts
I have a lot of XML documents that have sections in that contain tags that can be of any name but will contain type,minOccurs,maxOccurs and have a description inside it. For instance name,description,definition and id below.



<?xml version="1.0" encoding="utf-8"?>
<topLevel name="insight">
 
<description>description number1</description>
 
<rights>
   
<privLevel>user</privLevel>
 
</rights>
 
<method name="graphCreate">
   
<description>graphCreate API</description>
   
<rights></rights>
   
<request>
     
<params>
       
<name type="xs:string" minOccurs="1" >
         
<description>A friendly name to identify the graph</description>
       
</name>
       
<description type="xs:string" minOccurs="1" >
         
<description>Detailed description of the graph</description>
       
</description>        
       
<definition type="graphDefinition" minOccurs="1" maxOccurs="1">
         
<description>Specify the graph definition. i.e how this graph should be built.</description>
       
</definition>
     
</params>
   
</request>
   
<response>
     
<params>
   
<id type="xs:unsignedInt" minOccurs="1" >
         
<description>graph identifier.</description>
       
</id>
     
</params>
   
</response>
 
</method>
 
</topLevel>

Whats the best way to parse this. So far I have but can't work out how to dynamically generate the struct to stuff this into. Any suggestions?

type topLevel struct {
       
Description string   `xml:"description"`
       
Rights      rights   `xml:"rights"`
       
Method      []method `xml:"method"`
}


type method
struct {
       
Name        string  `xml:"name,attr"`
       
Description string  `xml:"description"`
       
Rights      []right `xml:"rights"`
}


type right
struct {
       
Right string `xml:"right"`
}


type request
struct {
}


type rights
struct {
       
PrivLevel string `xml:"privLevel"`
}

Meldingen er slettet

Jim Cote

ulest,
19. okt. 2017, 12:07:3119.10.2017
til golang-nuts
You'll need to use an UnmarshalXML func for the params:

// Param is a tag w/ any name
type
Param struct {
   
Name        string `xml:"-"`
   
Type        string `xml:"type,attr"`
   
MinOccurs   int    `xml:"minOccurs,attr"`
   
MaxOccurs   int    `xml:"maxOccurs,attr"`
   
Description string `xml:"description"`
}


// ParamList type for unmarhsal
type
ParamList []Param


// UnmarshalXML for the win
func
(pl *ParamList) UnmarshalXML(d *xml.Decoder, s xml.StartElement) error {
    tk
, err := d.Token()
   
for err == nil {
       
switch t := tk.(type) {
       
case xml.StartElement:
            param
:= Param{Name: t.Name.Local}
           
if err = d.DecodeElement(&param, &t); err != nil {
               
return err
           
}
           
*pl = append(*pl, param)
         
}
         
if tk, err = d.Token(); err == io.EOF {
             
return nil
         
}
   
}
   
return err
}


// TopLevel is of course top level
type
TopLevel struct {
   
Description string   `xml:"description"`
   
Rights      Rights   `xml:"rights"`
   
Method      []Method `xml:"method"`
}


// Method has request
type
Method struct {

   
Name        string   `xml:"name,attr"`
   
Description string   `xml:"description"`

   
Rights      []Right  `xml:"rights"`
   
Request     Request  `xml:"request"`
   
Response    Response `xml:"response"`
}


// Right whatever
type
Right struct {
   
Right string `xml:"right"`
}


// Request like Response
type
Request struct {
   
Params ParamList `xml:"params"`
}


// Response like Request
type
Response struct {
   
Params ParamList `xml:"params"`
}


// Rights
type
Rights struct {
   
PrivLevel string `xml:"privLevel"`
}
Svar alle
Svar til forfatter
Videresend
0 nye meldinger