xml.go 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. package stream
  2. import (
  3. "bytes"
  4. "encoding/xml"
  5. "github.com/kpmy/ypk/halt"
  6. "reflect"
  7. )
  8. func spl1t(bunch []byte) (ret chan []byte) {
  9. ret = make(chan []byte)
  10. go func() {
  11. d := xml.NewDecoder(bytes.NewReader(bunch))
  12. d.Strict = false
  13. var (
  14. _t xml.Token
  15. err error
  16. buf *bytes.Buffer
  17. e *xml.Encoder
  18. )
  19. init := func() {
  20. buf = bytes.NewBuffer(nil)
  21. e = xml.NewEncoder(buf)
  22. }
  23. flush := func() {
  24. e.Flush()
  25. if buf.Len() > 0 {
  26. ret <- buf.Bytes()
  27. }
  28. init()
  29. }
  30. join := func(n xml.Name) (ret string) {
  31. if n.Space != "" {
  32. ret = n.Space + ":"
  33. }
  34. ret = ret + n.Local
  35. return
  36. }
  37. depth := 0
  38. init()
  39. for stop := false; !stop && err == nil; {
  40. if _t, err = d.RawToken(); err == nil {
  41. switch t := _t.(type) {
  42. case xml.ProcInst:
  43. e.EncodeToken(t.Copy())
  44. case xml.StartElement:
  45. tt := t.Copy()
  46. tt.Name = xml.Name{Local: join(t.Name)}
  47. var tmp []xml.Attr
  48. for _, a := range tt.Attr {
  49. a.Name = xml.Name{Local: join(a.Name)}
  50. tmp = append(tmp, a)
  51. }
  52. tt.Attr = tmp
  53. e.EncodeToken(tt)
  54. depth++
  55. case xml.EndElement:
  56. tt := t
  57. tt.Name = xml.Name{Local: join(t.Name)}
  58. e.EncodeToken(tt)
  59. depth--
  60. if depth == 0 {
  61. flush()
  62. }
  63. case xml.CharData:
  64. e.EncodeToken(t)
  65. default:
  66. halt.As(100, reflect.TypeOf(t))
  67. }
  68. } else {
  69. flush()
  70. }
  71. }
  72. close(ret)
  73. }()
  74. return
  75. }