mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-15 13:19:53 +05:00
Replace library for cdrc xml with github.com/antchfx/xmlquery
This commit is contained in:
committed by
Dan Christian Bogos
parent
a07e4b1e39
commit
5c240017fd
30
cdrc/xml.go
30
cdrc/xml.go
@@ -26,7 +26,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/beevik/etree"
|
||||
"github.com/antchfx/xmlquery"
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
@@ -34,17 +34,18 @@ import (
|
||||
|
||||
// getElementText will process the node to extract the elementName's text out of it (only first one found)
|
||||
// returns utils.ErrNotFound if the element is not found in the node
|
||||
func elementText(xmlElement *etree.Element, elmntPath string) (string, error) {
|
||||
elmnt := xmlElement.FindElement(elmntPath)
|
||||
func elementText(xmlElement *xmlquery.Node, elmntPath string) (string, error) {
|
||||
elmnt := xmlquery.FindOne(xmlElement, elmntPath)
|
||||
if elmnt == nil {
|
||||
return "", utils.ErrNotFound
|
||||
}
|
||||
return elmnt.Text(), nil
|
||||
return elmnt.InnerText(), nil
|
||||
|
||||
}
|
||||
|
||||
// handlerUsageDiff will calculate the usage as difference between timeEnd and timeStart
|
||||
// Expects the 2 arguments in template separated by |
|
||||
func handlerSubstractUsage(xmlElement *etree.Element, argsTpl config.RSRParsers, cdrPath utils.HierarchyPath, timezone string) (time.Duration, error) {
|
||||
func handlerSubstractUsage(xmlElement *xmlquery.Node, argsTpl config.RSRParsers, cdrPath utils.HierarchyPath, timezone string) (time.Duration, error) {
|
||||
var argsStr string
|
||||
for _, rsrArg := range argsTpl {
|
||||
if rsrArg.Rules == utils.HandlerArgSep {
|
||||
@@ -79,21 +80,20 @@ func handlerSubstractUsage(xmlElement *etree.Element, argsTpl config.RSRParsers,
|
||||
|
||||
func NewXMLRecordsProcessor(recordsReader io.Reader, cdrPath utils.HierarchyPath, timezone string,
|
||||
httpSkipTlsCheck bool, cdrcCfgs []*config.CdrcConfig, filterS *engine.FilterS) (*XMLRecordsProcessor, error) {
|
||||
xmlDocument := etree.NewDocument() // create new document
|
||||
xmlDocument.ReadSettings.CharsetReader = func(label string, input io.Reader) (io.Reader, error) { // fix for enconding != UTF-8
|
||||
return input, nil
|
||||
}
|
||||
if _, err := xmlDocument.ReadFrom(recordsReader); err != nil { // read file and build xml document
|
||||
//create doc
|
||||
doc, err := xmlquery.Parse(recordsReader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
xmlProc := &XMLRecordsProcessor{cdrPath: cdrPath, timezone: timezone,
|
||||
httpSkipTlsCheck: httpSkipTlsCheck, cdrcCfgs: cdrcCfgs, filterS: filterS}
|
||||
xmlProc.cdrXmlElmts = xmlDocument.Root().FindElements(cdrPath.AsString("/", true))
|
||||
|
||||
xmlProc.cdrXmlElmts = xmlquery.Find(doc, cdrPath.AsString("/", true))
|
||||
return xmlProc, nil
|
||||
}
|
||||
|
||||
type XMLRecordsProcessor struct {
|
||||
cdrXmlElmts []*etree.Element // result of splitting the XML doc into CDR elements
|
||||
cdrXmlElmts []*xmlquery.Node // result of splitting the XML doc into CDR elements
|
||||
procItems int // current number of processed records from file
|
||||
cdrPath utils.HierarchyPath // path towards one CDR element
|
||||
timezone string
|
||||
@@ -137,7 +137,7 @@ func (xmlProc *XMLRecordsProcessor) ProcessNextRecord() (cdrs []*engine.CDR, err
|
||||
return cdrs, nil
|
||||
}
|
||||
|
||||
func (xmlProc *XMLRecordsProcessor) recordToCDR(xmlEntity *etree.Element, cdrcCfg *config.CdrcConfig, tenant string) (*engine.CDR, error) {
|
||||
func (xmlProc *XMLRecordsProcessor) recordToCDR(xmlEntity *xmlquery.Node, cdrcCfg *config.CdrcConfig, tenant string) (*engine.CDR, error) {
|
||||
cdr := &engine.CDR{OriginHost: "0.0.0.0", Source: cdrcCfg.CdrSourceId, ExtraFields: make(map[string]string), Cost: -1}
|
||||
var lazyHttpFields []*config.FCTemplate
|
||||
var err error
|
||||
@@ -206,14 +206,14 @@ func (xmlProc *XMLRecordsProcessor) recordToCDR(xmlEntity *etree.Element, cdrcCf
|
||||
}
|
||||
|
||||
// newXmlProvider constructs a DataProvider
|
||||
func newXmlProvider(req *etree.Element, cdrPath utils.HierarchyPath) (dP config.DataProvider) {
|
||||
func newXmlProvider(req *xmlquery.Node, cdrPath utils.HierarchyPath) (dP config.DataProvider) {
|
||||
dP = &xmlProvider{req: req, cdrPath: cdrPath, cache: config.NewNavigableMap(nil)}
|
||||
return
|
||||
}
|
||||
|
||||
// xmlProvider implements engine.DataProvider so we can pass it to filters
|
||||
type xmlProvider struct {
|
||||
req *etree.Element
|
||||
req *xmlquery.Node
|
||||
cdrPath utils.HierarchyPath //used to compute relative path
|
||||
cache *config.NavigableMap
|
||||
}
|
||||
|
||||
@@ -19,13 +19,13 @@ package cdrc
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"path"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/beevik/etree"
|
||||
"github.com/antchfx/xmlquery"
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
@@ -167,15 +167,11 @@ var cdrXmlBroadsoft = `<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
</broadWorksCDR>`
|
||||
|
||||
func TestXMLElementText(t *testing.T) {
|
||||
doc := etree.NewDocument()
|
||||
doc.ReadSettings.CharsetReader = func(label string, input io.Reader) (io.Reader, error) {
|
||||
return input, nil
|
||||
}
|
||||
if err := doc.ReadFromBytes([]byte(cdrXmlBroadsoft)); err != nil {
|
||||
doc, err := xmlquery.Parse(strings.NewReader(cdrXmlBroadsoft))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
cdrs := doc.FindElements(path.Join("/broadWorksCDR/cdrData/"))
|
||||
cdrs := xmlquery.Find(doc, path.Join("/broadWorksCDR/cdrData/"))
|
||||
cdrWithoutUserNr := cdrs[0]
|
||||
if _, err := elementText(cdrWithoutUserNr, "basicModule/userNumber"); err != utils.ErrNotFound {
|
||||
t.Error(err)
|
||||
@@ -194,15 +190,12 @@ func TestXMLElementText(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestXMLHandlerSubstractUsage(t *testing.T) {
|
||||
doc := etree.NewDocument()
|
||||
doc.ReadSettings.CharsetReader = func(label string, input io.Reader) (io.Reader, error) {
|
||||
return input, nil
|
||||
}
|
||||
if err := doc.ReadFromBytes([]byte(cdrXmlBroadsoft)); err != nil {
|
||||
doc, err := xmlquery.Parse(strings.NewReader(cdrXmlBroadsoft))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
cdrs := doc.FindElements(path.Join("/broadWorksCDR/cdrData/"))
|
||||
cdrs := xmlquery.Find(doc, path.Join("/broadWorksCDR/cdrData/"))
|
||||
cdrWithUsage := cdrs[1]
|
||||
if usage, err := handlerSubstractUsage(cdrWithUsage,
|
||||
config.NewRSRParsersMustCompile("~broadWorksCDR.cdrData.basicModule.releaseTime;|;~broadWorksCDR.cdrData.basicModule.answerTime", true),
|
||||
@@ -516,12 +509,12 @@ var xmlContent = `<?xml version="1.0" encoding="UTF-8"?>
|
||||
`
|
||||
|
||||
func TestXMLElementText3(t *testing.T) {
|
||||
doc := etree.NewDocument()
|
||||
if err := doc.ReadFromString(xmlContent); err != nil {
|
||||
doc, err := xmlquery.Parse(strings.NewReader(xmlContent))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
hPath2 := utils.ParseHierarchyPath("File.CDRs.Call", "")
|
||||
cdrs := doc.Root().FindElements(hPath2.AsString("/", true))
|
||||
cdrs := xmlquery.Find(doc, hPath2.AsString("/", true))
|
||||
if len(cdrs) != 3 {
|
||||
t.Errorf("Expecting: 3, received: %+v", len(cdrs))
|
||||
}
|
||||
@@ -530,11 +523,7 @@ func TestXMLElementText3(t *testing.T) {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
absolutePath := utils.ParseHierarchyPath("File.CDRs.Call.SignalingInfo.PChargingVector.icidvalue", "")
|
||||
hPath := utils.ParseHierarchyPath(cdrs[1].GetPath(), "")
|
||||
relPath := utils.HierarchyPath(absolutePath[len(hPath):]) // Need relative path to the xmlElmnt
|
||||
|
||||
if val, err := elementText(cdrs[1], relPath.AsString("/", false)); err != nil {
|
||||
if val, err := elementText(cdrs[1], "SignalingInfo/PChargingVector/icidvalue"); err != nil {
|
||||
t.Error(err)
|
||||
} else if val != "46d7974398c2671016afccc3f2c428c7" {
|
||||
t.Errorf("Expecting: 46d7974398c2671016afccc3f2c428c7, received: %s", val)
|
||||
|
||||
6
glide.lock
generated
6
glide.lock
generated
@@ -105,6 +105,8 @@ imports:
|
||||
- internal/scram
|
||||
- name: github.com/dlintw/goconf
|
||||
version: dcc070983490608a14480e3bf943bad464785df5
|
||||
- name: github.com/beevik/etree
|
||||
version: 90dafc1e1f114dfb9576218bb43c03fb854d1b34
|
||||
- name: github.com/antchfx/xmlquery
|
||||
version: 07935b1c0f2e6f0efa02c98cd70e223d70218955
|
||||
- name: github.com/antchfx/xpath
|
||||
version: 3de91f3991a1af6e495d49c9218318b5544b20e3
|
||||
testImports: []
|
||||
|
||||
@@ -41,4 +41,5 @@ import:
|
||||
- package: github.com/cgrates/radigo
|
||||
- package: github.com/cgrates/ltcache
|
||||
- package: github.com/dlintw/goconf
|
||||
- package: github.com/beevik/etree
|
||||
- package: github.com/antchfx/xmlquery
|
||||
- package: github.com/antchfx/xpath
|
||||
Reference in New Issue
Block a user