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)
...
...
parsing xml go
add a comment |
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)
...
...
parsing xml go
add a comment |
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)
...
...
parsing xml go
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
parsing xml go
edited Aug 15 at 9:15
sineemore
1,518524
1,518524
asked Jul 11 at 6:21
Евгений Гусев
365
365
add a comment |
add a comment |
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.
add a comment |
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.
add a comment |
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.
add a comment |
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.
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.
answered Aug 15 at 8:51
sineemore
1,518524
1,518524
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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