XML file parsing in Go











up vote
0
down vote

favorite












Below is a piece of code that is responsible for serializing files.
ZL_LIST and PERS_LIST are XML file structs, I have not shown them here to save space.



Please check my code.



package parser

import (
"encoding/xml"
"fmt"
"golang.org/x/text/encoding/charmap"
"io"
"io/ioutil"
"os"
"path/filepath"
"sync"
)

type Files struct {
Name string
PathZipFile string
PathUnzipFile string
}

type nameMap map[string]bool

func (ZL_LIST) Parse(FilesName *Files) {
unzipPath, err := filepath.Abs("tmp")

files, err := ioutil.ReadDir(unzipPath)
f := make(*Files, 0)
for _, file := range files {
fileZip := new(Files)
if !file.IsDir() && file.Name()[:1] != "." {
fileZip.Name = file.Name()
fileZip.PathUnzipFile = filepath.Join(unzipPath, file.Name())
f = append(f, fileZip)
}
}

if err != nil {
fmt.Printf("[ERROR] Error retrieving files %v", err)
}

names := make(nameMap, 1)
var wg sync.WaitGroup
var countHmLmFiles int = -1
var countHmFiles int = 0
var countLmFiles int = 0
var file *Files
for countHmLmFiles, file = range f {
wg.Add(1)
go func(filename *Files) {
parseHmLm(filename, &countHmFiles, &countLmFiles, &names)
wg.Done()
}(file)
}
wg.Wait()

fmt.Printf("[INFO] Read %d files from them HM files %d and LM files %d ", countHmLmFiles+1, countHmFiles, countLmFiles)
}

func parseHmLm(filename *Files, countHmFiles *int, countLmFiles *int, names *nameMap) {
fmt.Println("[INFO] считывается файл ", filename.Name, " с заголовком ", filename.Name[:2])
xmlFile, err := os.Open(filepath.Join(filename.PathUnzipFile))
if err != nil {
fmt.Printf("[ERROR] Cannot open file %e n", err)
}

defer xmlFile.Close()

switch filename.Name[:2] {
case "HM":
(*names)[filename.Name] = true
(*countHmFiles) += 1
var hFile ZL_LIST
decoder := xml.NewDecoder(xmlFile)
decoder.CharsetReader = charset
err := decoder.Decode(&hFile)
if err != nil {
fmt.Errorf("[ERROR] Cannot decode file %e", err)
}
case "LM":
(*countLmFiles) += 1
var lFile PERS_LIST
decoder := xml.NewDecoder(xmlFile)
decoder.CharsetReader = charset
err := decoder.Decode(&lFile)
if err != nil {
fmt.Errorf("[ERROR] Cannot decode file %e", err)
}
}

}

func charset(charset string, input io.Reader) (io.Reader, error) {
switch charset {
case "windows-1251":
return charmap.Windows1251.NewDecoder().Reader(input), nil
default:
return nil, fmt.Errorf("unknown charset: %s", charset)
}
}


Calling function



package api
import (
"net/http"
"github.com/go-chi/render"
"../../store/parser"
"fmt"
"path/filepath"
)
func (s *Rest) parse(w http.ResponseWriter, r *http.Request) {
uploadPath, err := filepath.Abs("./upload/")
if err != nil {
fmt.Printf("[ERROR] can not find the specified path %e", err)
}
unzipPath, err := filepath.Abs("./tmp")
if err != nil {
fmt.Printf("[ERROR] can not find the specified path %e", err)
}
p := parser.Files{}
filesName := p.GetFileName(uploadPath, unzipPath)
p.UnzipFiles(filesName, unzipPath)
...
...









share|improve this question




























    up vote
    0
    down vote

    favorite












    Below is a piece of code that is responsible for serializing files.
    ZL_LIST and PERS_LIST are XML file structs, I have not shown them here to save space.



    Please check my code.



    package parser

    import (
    "encoding/xml"
    "fmt"
    "golang.org/x/text/encoding/charmap"
    "io"
    "io/ioutil"
    "os"
    "path/filepath"
    "sync"
    )

    type Files struct {
    Name string
    PathZipFile string
    PathUnzipFile string
    }

    type nameMap map[string]bool

    func (ZL_LIST) Parse(FilesName *Files) {
    unzipPath, err := filepath.Abs("tmp")

    files, err := ioutil.ReadDir(unzipPath)
    f := make(*Files, 0)
    for _, file := range files {
    fileZip := new(Files)
    if !file.IsDir() && file.Name()[:1] != "." {
    fileZip.Name = file.Name()
    fileZip.PathUnzipFile = filepath.Join(unzipPath, file.Name())
    f = append(f, fileZip)
    }
    }

    if err != nil {
    fmt.Printf("[ERROR] Error retrieving files %v", err)
    }

    names := make(nameMap, 1)
    var wg sync.WaitGroup
    var countHmLmFiles int = -1
    var countHmFiles int = 0
    var countLmFiles int = 0
    var file *Files
    for countHmLmFiles, file = range f {
    wg.Add(1)
    go func(filename *Files) {
    parseHmLm(filename, &countHmFiles, &countLmFiles, &names)
    wg.Done()
    }(file)
    }
    wg.Wait()

    fmt.Printf("[INFO] Read %d files from them HM files %d and LM files %d ", countHmLmFiles+1, countHmFiles, countLmFiles)
    }

    func parseHmLm(filename *Files, countHmFiles *int, countLmFiles *int, names *nameMap) {
    fmt.Println("[INFO] считывается файл ", filename.Name, " с заголовком ", filename.Name[:2])
    xmlFile, err := os.Open(filepath.Join(filename.PathUnzipFile))
    if err != nil {
    fmt.Printf("[ERROR] Cannot open file %e n", err)
    }

    defer xmlFile.Close()

    switch filename.Name[:2] {
    case "HM":
    (*names)[filename.Name] = true
    (*countHmFiles) += 1
    var hFile ZL_LIST
    decoder := xml.NewDecoder(xmlFile)
    decoder.CharsetReader = charset
    err := decoder.Decode(&hFile)
    if err != nil {
    fmt.Errorf("[ERROR] Cannot decode file %e", err)
    }
    case "LM":
    (*countLmFiles) += 1
    var lFile PERS_LIST
    decoder := xml.NewDecoder(xmlFile)
    decoder.CharsetReader = charset
    err := decoder.Decode(&lFile)
    if err != nil {
    fmt.Errorf("[ERROR] Cannot decode file %e", err)
    }
    }

    }

    func charset(charset string, input io.Reader) (io.Reader, error) {
    switch charset {
    case "windows-1251":
    return charmap.Windows1251.NewDecoder().Reader(input), nil
    default:
    return nil, fmt.Errorf("unknown charset: %s", charset)
    }
    }


    Calling function



    package api
    import (
    "net/http"
    "github.com/go-chi/render"
    "../../store/parser"
    "fmt"
    "path/filepath"
    )
    func (s *Rest) parse(w http.ResponseWriter, r *http.Request) {
    uploadPath, err := filepath.Abs("./upload/")
    if err != nil {
    fmt.Printf("[ERROR] can not find the specified path %e", err)
    }
    unzipPath, err := filepath.Abs("./tmp")
    if err != nil {
    fmt.Printf("[ERROR] can not find the specified path %e", err)
    }
    p := parser.Files{}
    filesName := p.GetFileName(uploadPath, unzipPath)
    p.UnzipFiles(filesName, unzipPath)
    ...
    ...









    share|improve this question


























      up vote
      0
      down vote

      favorite









      up vote
      0
      down vote

      favorite











      Below is a piece of code that is responsible for serializing files.
      ZL_LIST and PERS_LIST are XML file structs, I have not shown them here to save space.



      Please check my code.



      package parser

      import (
      "encoding/xml"
      "fmt"
      "golang.org/x/text/encoding/charmap"
      "io"
      "io/ioutil"
      "os"
      "path/filepath"
      "sync"
      )

      type Files struct {
      Name string
      PathZipFile string
      PathUnzipFile string
      }

      type nameMap map[string]bool

      func (ZL_LIST) Parse(FilesName *Files) {
      unzipPath, err := filepath.Abs("tmp")

      files, err := ioutil.ReadDir(unzipPath)
      f := make(*Files, 0)
      for _, file := range files {
      fileZip := new(Files)
      if !file.IsDir() && file.Name()[:1] != "." {
      fileZip.Name = file.Name()
      fileZip.PathUnzipFile = filepath.Join(unzipPath, file.Name())
      f = append(f, fileZip)
      }
      }

      if err != nil {
      fmt.Printf("[ERROR] Error retrieving files %v", err)
      }

      names := make(nameMap, 1)
      var wg sync.WaitGroup
      var countHmLmFiles int = -1
      var countHmFiles int = 0
      var countLmFiles int = 0
      var file *Files
      for countHmLmFiles, file = range f {
      wg.Add(1)
      go func(filename *Files) {
      parseHmLm(filename, &countHmFiles, &countLmFiles, &names)
      wg.Done()
      }(file)
      }
      wg.Wait()

      fmt.Printf("[INFO] Read %d files from them HM files %d and LM files %d ", countHmLmFiles+1, countHmFiles, countLmFiles)
      }

      func parseHmLm(filename *Files, countHmFiles *int, countLmFiles *int, names *nameMap) {
      fmt.Println("[INFO] считывается файл ", filename.Name, " с заголовком ", filename.Name[:2])
      xmlFile, err := os.Open(filepath.Join(filename.PathUnzipFile))
      if err != nil {
      fmt.Printf("[ERROR] Cannot open file %e n", err)
      }

      defer xmlFile.Close()

      switch filename.Name[:2] {
      case "HM":
      (*names)[filename.Name] = true
      (*countHmFiles) += 1
      var hFile ZL_LIST
      decoder := xml.NewDecoder(xmlFile)
      decoder.CharsetReader = charset
      err := decoder.Decode(&hFile)
      if err != nil {
      fmt.Errorf("[ERROR] Cannot decode file %e", err)
      }
      case "LM":
      (*countLmFiles) += 1
      var lFile PERS_LIST
      decoder := xml.NewDecoder(xmlFile)
      decoder.CharsetReader = charset
      err := decoder.Decode(&lFile)
      if err != nil {
      fmt.Errorf("[ERROR] Cannot decode file %e", err)
      }
      }

      }

      func charset(charset string, input io.Reader) (io.Reader, error) {
      switch charset {
      case "windows-1251":
      return charmap.Windows1251.NewDecoder().Reader(input), nil
      default:
      return nil, fmt.Errorf("unknown charset: %s", charset)
      }
      }


      Calling function



      package api
      import (
      "net/http"
      "github.com/go-chi/render"
      "../../store/parser"
      "fmt"
      "path/filepath"
      )
      func (s *Rest) parse(w http.ResponseWriter, r *http.Request) {
      uploadPath, err := filepath.Abs("./upload/")
      if err != nil {
      fmt.Printf("[ERROR] can not find the specified path %e", err)
      }
      unzipPath, err := filepath.Abs("./tmp")
      if err != nil {
      fmt.Printf("[ERROR] can not find the specified path %e", err)
      }
      p := parser.Files{}
      filesName := p.GetFileName(uploadPath, unzipPath)
      p.UnzipFiles(filesName, unzipPath)
      ...
      ...









      share|improve this question















      Below is a piece of code that is responsible for serializing files.
      ZL_LIST and PERS_LIST are XML file structs, I have not shown them here to save space.



      Please check my code.



      package parser

      import (
      "encoding/xml"
      "fmt"
      "golang.org/x/text/encoding/charmap"
      "io"
      "io/ioutil"
      "os"
      "path/filepath"
      "sync"
      )

      type Files struct {
      Name string
      PathZipFile string
      PathUnzipFile string
      }

      type nameMap map[string]bool

      func (ZL_LIST) Parse(FilesName *Files) {
      unzipPath, err := filepath.Abs("tmp")

      files, err := ioutil.ReadDir(unzipPath)
      f := make(*Files, 0)
      for _, file := range files {
      fileZip := new(Files)
      if !file.IsDir() && file.Name()[:1] != "." {
      fileZip.Name = file.Name()
      fileZip.PathUnzipFile = filepath.Join(unzipPath, file.Name())
      f = append(f, fileZip)
      }
      }

      if err != nil {
      fmt.Printf("[ERROR] Error retrieving files %v", err)
      }

      names := make(nameMap, 1)
      var wg sync.WaitGroup
      var countHmLmFiles int = -1
      var countHmFiles int = 0
      var countLmFiles int = 0
      var file *Files
      for countHmLmFiles, file = range f {
      wg.Add(1)
      go func(filename *Files) {
      parseHmLm(filename, &countHmFiles, &countLmFiles, &names)
      wg.Done()
      }(file)
      }
      wg.Wait()

      fmt.Printf("[INFO] Read %d files from them HM files %d and LM files %d ", countHmLmFiles+1, countHmFiles, countLmFiles)
      }

      func parseHmLm(filename *Files, countHmFiles *int, countLmFiles *int, names *nameMap) {
      fmt.Println("[INFO] считывается файл ", filename.Name, " с заголовком ", filename.Name[:2])
      xmlFile, err := os.Open(filepath.Join(filename.PathUnzipFile))
      if err != nil {
      fmt.Printf("[ERROR] Cannot open file %e n", err)
      }

      defer xmlFile.Close()

      switch filename.Name[:2] {
      case "HM":
      (*names)[filename.Name] = true
      (*countHmFiles) += 1
      var hFile ZL_LIST
      decoder := xml.NewDecoder(xmlFile)
      decoder.CharsetReader = charset
      err := decoder.Decode(&hFile)
      if err != nil {
      fmt.Errorf("[ERROR] Cannot decode file %e", err)
      }
      case "LM":
      (*countLmFiles) += 1
      var lFile PERS_LIST
      decoder := xml.NewDecoder(xmlFile)
      decoder.CharsetReader = charset
      err := decoder.Decode(&lFile)
      if err != nil {
      fmt.Errorf("[ERROR] Cannot decode file %e", err)
      }
      }

      }

      func charset(charset string, input io.Reader) (io.Reader, error) {
      switch charset {
      case "windows-1251":
      return charmap.Windows1251.NewDecoder().Reader(input), nil
      default:
      return nil, fmt.Errorf("unknown charset: %s", charset)
      }
      }


      Calling function



      package api
      import (
      "net/http"
      "github.com/go-chi/render"
      "../../store/parser"
      "fmt"
      "path/filepath"
      )
      func (s *Rest) parse(w http.ResponseWriter, r *http.Request) {
      uploadPath, err := filepath.Abs("./upload/")
      if err != nil {
      fmt.Printf("[ERROR] can not find the specified path %e", err)
      }
      unzipPath, err := filepath.Abs("./tmp")
      if err != nil {
      fmt.Printf("[ERROR] can not find the specified path %e", err)
      }
      p := parser.Files{}
      filesName := p.GetFileName(uploadPath, unzipPath)
      p.UnzipFiles(filesName, unzipPath)
      ...
      ...






      parsing xml go






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Aug 15 at 9:15









      sineemore

      1,518524




      1,518524










      asked Jul 11 at 6:21









      Евгений Гусев

      365




      365






















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          0
          down vote













          Variables



          Go has two ways of declaring new variables: a var notation and a short one. It's preferable to use the short one:



          wg := sync.WaitGroup{}
          countHmLmFiles := -1
          countHmFiles := 0
          countLmFiles := 0


          Also when declaring lots of global variables in the package block you may use block notation:



          var (
          a int = 1
          b string = "foo"
          )


          You can declare variables directly in the for loop:



          for countHmLmFiles, file := range f {
          // countHmLmFiles and file will be visible only here
          }


          This way their scope will be limited to for body.



          Maps in Go



          You've created a map with make:



          names := make(nameMap, 1)


          I don't see a point in creating a map for a single element. Also when you don't need the size argument in make you may simply write names := nameMap{}.



          No need pass maps with pointer. Maps and slices are already a reference type and may be passed directly by value. It won't issue a full copy.



          Error handling



          You've missed lots of error checks. Ideally every error must be handled in place. Otherwise use _ to ignore it and make a comment to be specific on this as it looks like a broken code.



          The switch lacks the default case. It worth adding it to catch other possible values of filename.Name[:2].



          Also don't forget to add terminating n to fmt.Printf to separate log messages.






          share|improve this answer





















            Your Answer





            StackExchange.ifUsing("editor", function () {
            return StackExchange.using("mathjaxEditing", function () {
            StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
            StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
            });
            });
            }, "mathjax-editing");

            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "196"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            convertImagesToLinks: false,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














             

            draft saved


            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f198261%2fxml-file-parsing-in-go%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            0
            down vote













            Variables



            Go has two ways of declaring new variables: a var notation and a short one. It's preferable to use the short one:



            wg := sync.WaitGroup{}
            countHmLmFiles := -1
            countHmFiles := 0
            countLmFiles := 0


            Also when declaring lots of global variables in the package block you may use block notation:



            var (
            a int = 1
            b string = "foo"
            )


            You can declare variables directly in the for loop:



            for countHmLmFiles, file := range f {
            // countHmLmFiles and file will be visible only here
            }


            This way their scope will be limited to for body.



            Maps in Go



            You've created a map with make:



            names := make(nameMap, 1)


            I don't see a point in creating a map for a single element. Also when you don't need the size argument in make you may simply write names := nameMap{}.



            No need pass maps with pointer. Maps and slices are already a reference type and may be passed directly by value. It won't issue a full copy.



            Error handling



            You've missed lots of error checks. Ideally every error must be handled in place. Otherwise use _ to ignore it and make a comment to be specific on this as it looks like a broken code.



            The switch lacks the default case. It worth adding it to catch other possible values of filename.Name[:2].



            Also don't forget to add terminating n to fmt.Printf to separate log messages.






            share|improve this answer

























              up vote
              0
              down vote













              Variables



              Go has two ways of declaring new variables: a var notation and a short one. It's preferable to use the short one:



              wg := sync.WaitGroup{}
              countHmLmFiles := -1
              countHmFiles := 0
              countLmFiles := 0


              Also when declaring lots of global variables in the package block you may use block notation:



              var (
              a int = 1
              b string = "foo"
              )


              You can declare variables directly in the for loop:



              for countHmLmFiles, file := range f {
              // countHmLmFiles and file will be visible only here
              }


              This way their scope will be limited to for body.



              Maps in Go



              You've created a map with make:



              names := make(nameMap, 1)


              I don't see a point in creating a map for a single element. Also when you don't need the size argument in make you may simply write names := nameMap{}.



              No need pass maps with pointer. Maps and slices are already a reference type and may be passed directly by value. It won't issue a full copy.



              Error handling



              You've missed lots of error checks. Ideally every error must be handled in place. Otherwise use _ to ignore it and make a comment to be specific on this as it looks like a broken code.



              The switch lacks the default case. It worth adding it to catch other possible values of filename.Name[:2].



              Also don't forget to add terminating n to fmt.Printf to separate log messages.






              share|improve this answer























                up vote
                0
                down vote










                up vote
                0
                down vote









                Variables



                Go has two ways of declaring new variables: a var notation and a short one. It's preferable to use the short one:



                wg := sync.WaitGroup{}
                countHmLmFiles := -1
                countHmFiles := 0
                countLmFiles := 0


                Also when declaring lots of global variables in the package block you may use block notation:



                var (
                a int = 1
                b string = "foo"
                )


                You can declare variables directly in the for loop:



                for countHmLmFiles, file := range f {
                // countHmLmFiles and file will be visible only here
                }


                This way their scope will be limited to for body.



                Maps in Go



                You've created a map with make:



                names := make(nameMap, 1)


                I don't see a point in creating a map for a single element. Also when you don't need the size argument in make you may simply write names := nameMap{}.



                No need pass maps with pointer. Maps and slices are already a reference type and may be passed directly by value. It won't issue a full copy.



                Error handling



                You've missed lots of error checks. Ideally every error must be handled in place. Otherwise use _ to ignore it and make a comment to be specific on this as it looks like a broken code.



                The switch lacks the default case. It worth adding it to catch other possible values of filename.Name[:2].



                Also don't forget to add terminating n to fmt.Printf to separate log messages.






                share|improve this answer












                Variables



                Go has two ways of declaring new variables: a var notation and a short one. It's preferable to use the short one:



                wg := sync.WaitGroup{}
                countHmLmFiles := -1
                countHmFiles := 0
                countLmFiles := 0


                Also when declaring lots of global variables in the package block you may use block notation:



                var (
                a int = 1
                b string = "foo"
                )


                You can declare variables directly in the for loop:



                for countHmLmFiles, file := range f {
                // countHmLmFiles and file will be visible only here
                }


                This way their scope will be limited to for body.



                Maps in Go



                You've created a map with make:



                names := make(nameMap, 1)


                I don't see a point in creating a map for a single element. Also when you don't need the size argument in make you may simply write names := nameMap{}.



                No need pass maps with pointer. Maps and slices are already a reference type and may be passed directly by value. It won't issue a full copy.



                Error handling



                You've missed lots of error checks. Ideally every error must be handled in place. Otherwise use _ to ignore it and make a comment to be specific on this as it looks like a broken code.



                The switch lacks the default case. It worth adding it to catch other possible values of filename.Name[:2].



                Also don't forget to add terminating n to fmt.Printf to separate log messages.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Aug 15 at 8:51









                sineemore

                1,518524




                1,518524






























                     

                    draft saved


                    draft discarded



















































                     


                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f198261%2fxml-file-parsing-in-go%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Сан-Квентин

                    8-я гвардейская общевойсковая армия

                    Алькесар