fixes
This commit is contained in:
@@ -16,32 +16,34 @@ var eprelIDKeys = []string{
|
||||
}
|
||||
|
||||
// NormalizeID coerces XML/API values (string, number, {"#text": ...}) to a trimmed ID.
|
||||
// Placeholder feed values like "0" / "0000" become empty so the EPREL step is not
|
||||
// falsely "skipped" after a doomed fetch attempt.
|
||||
func NormalizeID(v any) string {
|
||||
if v == nil {
|
||||
return ""
|
||||
}
|
||||
var s string
|
||||
switch t := v.(type) {
|
||||
case string:
|
||||
return strings.TrimSpace(t)
|
||||
s = strings.TrimSpace(t)
|
||||
case json.Number:
|
||||
s := strings.TrimSpace(t.String())
|
||||
s = strings.TrimSpace(t.String())
|
||||
if i := strings.IndexByte(s, '.'); i >= 0 {
|
||||
s = s[:i]
|
||||
}
|
||||
return s
|
||||
case float64:
|
||||
if t != t { // NaN
|
||||
return ""
|
||||
}
|
||||
return strconv.FormatInt(int64(t), 10)
|
||||
s = strconv.FormatInt(int64(t), 10)
|
||||
case float32:
|
||||
return strconv.FormatInt(int64(t), 10)
|
||||
s = strconv.FormatInt(int64(t), 10)
|
||||
case int:
|
||||
return strconv.Itoa(t)
|
||||
s = strconv.Itoa(t)
|
||||
case int64:
|
||||
return strconv.FormatInt(t, 10)
|
||||
s = strconv.FormatInt(t, 10)
|
||||
case int32:
|
||||
return strconv.FormatInt(int64(t), 10)
|
||||
s = strconv.FormatInt(int64(t), 10)
|
||||
case json.RawMessage:
|
||||
var decoded any
|
||||
if err := json.Unmarshal(t, &decoded); err != nil {
|
||||
@@ -55,14 +57,44 @@ func NormalizeID(v any) string {
|
||||
if text, ok := t["text"]; ok {
|
||||
return NormalizeID(text)
|
||||
}
|
||||
return ""
|
||||
case []any:
|
||||
for _, item := range t {
|
||||
if id := NormalizeID(item); id != "" {
|
||||
return id
|
||||
}
|
||||
}
|
||||
return ""
|
||||
case []string:
|
||||
for _, item := range t {
|
||||
if id := NormalizeID(item); id != "" {
|
||||
return id
|
||||
}
|
||||
}
|
||||
return ""
|
||||
default:
|
||||
s := strings.TrimSpace(fmt.Sprint(t))
|
||||
s = strings.TrimSpace(fmt.Sprint(t))
|
||||
if s == "" || s == "<nil>" {
|
||||
return ""
|
||||
}
|
||||
return s
|
||||
}
|
||||
return ""
|
||||
if isPlaceholderEPRELID(s) {
|
||||
return ""
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func isPlaceholderEPRELID(id string) bool {
|
||||
id = strings.TrimSpace(id)
|
||||
if id == "" {
|
||||
return true
|
||||
}
|
||||
for _, r := range id {
|
||||
if r != '0' {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// IsValidID reports whether v normalizes to a non-empty EPREL registration id.
|
||||
@@ -70,8 +102,8 @@ func IsValidID(v any) bool {
|
||||
return NormalizeID(v) != ""
|
||||
}
|
||||
|
||||
// ExtractID finds an EPREL ID in mapped and/or raw product field maps
|
||||
// (vendor feeds often use <EPRELID/> / eprel_id).
|
||||
// ExtractID finds an EPREL ID in mapped, raw, and/or attribute field maps
|
||||
// (vendor feeds often use <EPRELID/> / eprel_id; specs parse may put it only in attrs).
|
||||
func ExtractID(sources ...map[string]any) string {
|
||||
for _, src := range sources {
|
||||
if src == nil {
|
||||
|
||||
Reference in New Issue
Block a user