go-xml icon indicating copy to clipboard operation
go-xml copied to clipboard

Failed to parse chardata.

Open yuanhuili opened this issue 4 years ago • 2 comments

  • I have an xml file, and a part of the string is as follows:
    <userdatatype>module
        <dataTypeEnum schemanode="" description="" declareType="ExportAll" name="ISOLATIONMODE"/>
    </userdatatype>

When I parse the xml above using the following code ,the code is as follows:

	ele,err:=xmltree.Parse(data)
	xmltree.Unmarshal(ele,v)
	if err != nil {
		fmt.Printf("error: %v", err)
		return
	}

The corresponding structure is as follows:

type Cuserdatatype struct {
	XMLName       xml.Name       `sxml:"userdatatype,omitempty" json:"userdatatype,omitempty"`
	CdataTypeEnum *CdataTypeEnum `xml:"dataTypeEnum,omitempty" json:"dataTypeEnum,omitempty"`
	CString        string         `xml:",chardata" json:",omitempty"`
}

The parsed result "module" is lost!! image

ps:but when I use the native parser. "moudle" is not lost.

 xml.Unmarshal(data, v)

image

Why?

yuanhuili avatar Jan 22 '21 03:01 yuanhuili

ps:v := &Cmodule{}

yuanhuili avatar Jan 22 '21 03:01 yuanhuili

It's a bug. This piece of code in marshal.go

if len(el.Children) == 0 {
	if len(el.Content) > 0 {
		e.w.Write(el.Content)
	} else {
		return nil
	}
}

The Marshal function only writes out .Content (which includes the chardata) if there are no child elements. I could write out .Content unconditionally, but the problem is that .Content also contains the XML for child elements, and it will not reflect any changes made to the tree after Parse.

I'm not sure what's best here. I guess we could include xml.CharData in the decode switch here, add a .CharData field to Element, and work that into the encoder. The Marshal output would look different from the source document, but I think it should be good enough for the example here.

droyo avatar Jan 22 '21 05:01 droyo