tablib_xml.go 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. package tablib
  2. import (
  3. "bytes"
  4. "github.com/agrison/mxj"
  5. )
  6. // XML returns a XML representation of the Dataset as an Exportable.
  7. func (d *Dataset) XML() (*Exportable, error) {
  8. return d.XMLWithTagNamePrefixIndent("row", " ", " ")
  9. }
  10. // XML returns a XML representation of the Databook as an Exportable.
  11. func (d *Databook) XML() (*Exportable, error) {
  12. b := newBuffer()
  13. b.WriteString("<databook>\n")
  14. for _, s := range d.sheets {
  15. b.WriteString(" <sheet>\n <title>" + s.title + "</title>\n ")
  16. row, err := s.dataset.XMLWithTagNamePrefixIndent("row", " ", " ")
  17. if err != nil {
  18. return nil, err
  19. }
  20. b.Write(row.Bytes())
  21. b.WriteString("\n </sheet>")
  22. }
  23. b.WriteString("\n</databook>")
  24. return newExportable(b), nil
  25. }
  26. // XMLWithTagNamePrefixIndent returns a XML representation with custom tag, prefix and indent.
  27. func (d *Dataset) XMLWithTagNamePrefixIndent(tagName, prefix, indent string) (*Exportable, error) {
  28. back := d.Dict()
  29. exportable := newExportable(newBuffer())
  30. exportable.buffer.WriteString("<dataset>\n")
  31. for _, r := range back {
  32. m := mxj.Map(r.(map[string]interface{}))
  33. if err := m.XmlIndentWriter(exportable.buffer, prefix, indent, tagName); err != nil {
  34. return nil, err
  35. }
  36. }
  37. exportable.buffer.WriteString("\n" + prefix + "</dataset>")
  38. return exportable, nil
  39. }
  40. // LoadXML loads a Dataset from an XML source.
  41. func LoadXML(input []byte) (*Dataset, error) {
  42. m, _, err := mxj.NewMapXmlReaderRaw(bytes.NewReader(input))
  43. if err != nil {
  44. return nil, err
  45. }
  46. // this seems quite a bit hacky
  47. datasetNode, _ := m.ValueForPath("dataset")
  48. rowNode := datasetNode.(map[string]interface{})["row"].([]interface{})
  49. back := make([]map[string]interface{}, 0, len(rowNode))
  50. for _, r := range rowNode {
  51. back = append(back, r.(map[string]interface{}))
  52. }
  53. return internalLoadFromDict(back)
  54. }