Skip to content

Commit

Permalink
Added option to output as XML
Browse files Browse the repository at this point in the history
  • Loading branch information
hectorcorrea committed Nov 12, 2020
1 parent 4738130 commit 7276447
Show file tree
Hide file tree
Showing 5 changed files with 143 additions and 9 deletions.
2 changes: 2 additions & 0 deletions cmd/marcli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ func main() {
err = toJson(params)
} else if format == "solr" {
err = toSolr(params)
} else if format == "xml" {
err = toXML(params)
} else {
err = errors.New("Invalid format")
}
Expand Down
11 changes: 2 additions & 9 deletions cmd/marcli/mrk.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,8 @@ func toMrk(params ProcessFileParams) error {

if err != nil {
str := "== RECORD WITH ERROR STARTS HERE\n"
str += "ERROR:\n"
str += err.Error() + "\n"
str += "PARSED:\n"
str += fmt.Sprintf("%s\r\n", r.Leader)
for _, field := range r.Fields {
str += fmt.Sprintf("%s\r\n", field)
}
str += "BINARY:\n"
str += fmt.Sprintf("%s\n", r.Data)
str += "ERROR:\n" + err.Error() + "\n"
str += r.DebugString() + "\n"
str += "== RECORD WITH ERROR ENDS HERE\n\n"
fmt.Print(str)
if params.debug {
Expand Down
124 changes: 124 additions & 0 deletions cmd/marcli/xml.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package main

import (
"encoding/xml"
"fmt"
"io"
"os"

"github.com/hectorcorrea/marcli/pkg/marc"
)

type controlField struct {
Tag string `xml:"tag,attr"`
Value string `xml:",chardata"`
}

type subfield struct {
Code string `xml:"code,attr"`
Value string `xml:",chardata"`
}
type dataField struct {
Tag string `xml:"tag,attr"`
Ind1 string `xml:"ind1,attr"`
Ind2 string `xml:"ind2,attr"`
Subfields []subfield `xml:"subfield"`
}

type xmlRecord struct {
XMLName xml.Name `xml:"record"`
Leader string `xml:"leader"`
ControlFields []controlField `xml:"controlfield"`
DataFields []dataField `xml:"datafield"`
}

const xmlProlog = `<?xml version="1.0" encoding="UTF-8"?>`
const xmlRootBegin = `<collection xmlns="http://www.loc.gov/MARC21/slim" xmlns:marc="http://www.loc.gov/MARC21/slim">`
const xmlRootEnd = `</collection>`

func toXML(params ProcessFileParams) error {
if count == 0 {
return nil
}

file, err := os.Open(params.filename)
if err != nil {
return err
}
defer file.Close()

fmt.Printf("%s\n%s\n", xmlProlog, xmlRootBegin)

var i, out int
marc := marc.NewMarcFile(file)
for marc.Scan() {

r, err := marc.Record()
if err == io.EOF {
break
}

if err != nil {
printError(r, "PARSE ERROR", err)
if params.debug {
continue
}
return err
}

if i++; i < start {
continue
}

if r.Contains(params.searchValue) && r.HasFields(params.hasFields) {
str, err := recordToXML(r, params.debug)
if err != nil {
if params.debug {
printError(r, "XML PARSE ERROR", err)
continue
}
panic(err)
}
fmt.Printf("%s\r\n", str)
if out++; out == count {
break
}
}
}
fmt.Printf("%s\n", xmlRootEnd)

return marc.Err()
}

func recordToXML(r marc.Record, debug bool) (string, error) {
x := xmlRecord{
Leader: r.Leader.Raw(),
}

for _, f := range r.Fields {
if f.IsControlField() {
x.ControlFields = append(x.ControlFields, controlField{Tag: f.Tag, Value: f.Value})
} else {
df := dataField{Tag: f.Tag, Ind1: f.Indicator1, Ind2: f.Indicator2}
for _, s := range f.SubFields {
df.Subfields = append(df.Subfields, subfield{Code: s.Code, Value: s.Value})
}
x.DataFields = append(x.DataFields, df)
}
}

indent := ""
if debug {
indent = " "
}
b, err := xml.MarshalIndent(x, indent, indent)
return string(b), err
}

func printError(r marc.Record, errType string, err error) {
str := "== RECORD WITH ERROR STARTS HERE\n"
str += fmt.Sprintf("%s:\n%s\n", errType, err.Error())
str += r.DebugString() + "\n"
str += "== RECORD WITH ERROR ENDS HERE\n\n"
fmt.Print(str)
}
4 changes: 4 additions & 0 deletions pkg/marc/leader.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,7 @@ func NewLeader(bytes []byte) (Leader, error) {
func (l Leader) String() string {
return fmt.Sprintf("=LDR %s", string(l.raw))
}

func (l Leader) Raw() string {
return string(l.raw)
}
11 changes: 11 additions & 0 deletions pkg/marc/record.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,17 @@ func (r Record) String() string {
return fmt.Sprintf("Leader: %s", r.Leader)
}

func (r Record) DebugString() string {
str := "PARSED:\n"
str += fmt.Sprintf("%s\r\n", r.Leader)
for _, field := range r.Fields {
str += fmt.Sprintf("%s\r\n", field)
}
str += "BINARY:\n"
str += fmt.Sprintf("%s", r.Data)
return str
}

// Filter returns the fields in the record that match
// the given filter.
func (r Record) Filter(include FieldFilters, exclude FieldFilters) []Field {
Expand Down

0 comments on commit 7276447

Please sign in to comment.