Repository: mmcdole/gofeed
Pull request #177 (2021-04-20 01:04:16)

Ability to parse custom fields in rss that are not part of the spec
I have a requirement to parse elements that are not part of the standard spec.  Noticed someone also recently raised this as part of the issue #174

Raising this pull request in case this will be helpful for others.

coveralls: 
[![Coverage Status](https://coveralls.io/builds/38952919/badge)](https://coveralls.io/builds/38952919)

Coverage decreased (-0.03%) to 74.542% when pulling **085960d6930ddc92e5f783fab4221cf8439e77c1 on sjawaji:master** into **41f47c9aa28b0731e0ac1b5a92830b1951ba91c9 on mmcdole:master**.

sjawaji: Will add more test cases.
sjawaji: @mmcdole - Added additional test cases.  Are you happy to merge this?
sjawaji: @mmcdole - possible to merge?  The feature is urgently needed for me.

Patch:
diff --git a/rss/feed.go b/rss/feed.go
index fc8041d..dd9c9e5 100644
--- a/rss/feed.go
+++ b/rss/feed.go
@@ -59,6 +59,7 @@ type Item struct {
 	DublinCoreExt *ext.DublinCoreExtension `json:"dcExt,omitempty"`
 	ITunesExt     *ext.ITunesItemExtension `json:"itunesExt,omitempty"`
 	Extensions    ext.Extensions           `json:"extensions,omitempty"`
+	Custom        map[string]string        `json:"custom,omitempty"`
 }
 
 // Image is an image that represents the feed
diff --git a/rss/parser.go b/rss/parser.go
index 684d160..1bbd46c 100644
--- a/rss/parser.go
+++ b/rss/parser.go
@@ -415,8 +415,14 @@ func (rp *Parser) parseItem(p *xpp.XMLPullParser) (item *Item, err error) {
 				}
 				categories = append(categories, result)
 			} else {
-				// Skip any elements not part of the item spec
-				p.Skip()
+				result, err := shared.ParseText(p)
+				if err != nil {
+					continue
+				}
+				if item.Custom == nil {
+					item.Custom = make(map[string]string, 0)
+				}
+				item.Custom[name] = result
 			}
 		}
 	}
diff --git a/translator.go b/translator.go
index d7aa0fa..6a71e3a 100644
--- a/translator.go
+++ b/translator.go
@@ -78,6 +78,7 @@ func (t *DefaultRSSTranslator) translateFeedItem(rssItem *rss.Item) (item *Item)
 	item.DublinCoreExt = rssItem.DublinCoreExt
 	item.ITunesExt = rssItem.ITunesExt
 	item.Extensions = rssItem.Extensions
+	item.Custom = rssItem.Custom
 	return
 }
 


Test patch:
diff --git a/testdata/parser/rss/rss_channel_item_custom.json b/testdata/parser/rss/rss_channel_item_custom.json
new file mode 100644
index 0000000..5e739a6
--- /dev/null
+++ b/testdata/parser/rss/rss_channel_item_custom.json
@@ -0,0 +1,11 @@
+{
+  "items": [
+    {
+      "custom": {
+        "apcategory": "s",
+        "test": "test"
+      }
+    }
+  ],
+  "version": "2.0"
+}
diff --git a/testdata/parser/rss/rss_channel_item_custom.xml b/testdata/parser/rss/rss_channel_item_custom.xml
new file mode 100644
index 0000000..fdc7c29
--- /dev/null
+++ b/testdata/parser/rss/rss_channel_item_custom.xml
@@ -0,0 +1,11 @@
+<!--
+Description: rss item categories 
+-->
+<rss version="2.0">
+  <channel>
+    <item>
+      <apcategory>s</apcategory>
+      <test>test</test>
+    </item>
+  </channel>
+</rss>
diff --git a/testdata/translator/rss/feed_item_category_-_rss_channel_item_custom.json b/testdata/translator/rss/feed_item_category_-_rss_channel_item_custom.json
new file mode 100644
index 0000000..24add26
--- /dev/null
+++ b/testdata/translator/rss/feed_item_category_-_rss_channel_item_custom.json
@@ -0,0 +1,12 @@
+{
+  "items": [
+    {
+      "custom": {
+        "apcategory": "s",
+        "test": "test"
+      }
+    }
+  ],
+  "feedType": "rss",
+  "feedVersion": "2.0"
+}
diff --git a/testdata/translator/rss/feed_item_category_-_rss_channel_item_custom.xml b/testdata/translator/rss/feed_item_category_-_rss_channel_item_custom.xml
new file mode 100644
index 0000000..b70463b
--- /dev/null
+++ b/testdata/translator/rss/feed_item_category_-_rss_channel_item_custom.xml
@@ -0,0 +1,8 @@
+<rss version="2.0">
+  <channel>
+    <item>
+      <test>test</test>
+      <apcategory>s</apcategory>
+    </item>
+  </channel>
+</rss>