Skip to content

Commit b724010

Browse files
author
PeterKrol
committed
Added the ability to automatically parse HTML tags
1 parent cf72dae commit b724010

16 files changed

+140
-62
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## [0.7.3](https://pub.dev/packages/webfeed-revised/versions/0.7.3)
4+
- Fixed html parser function
5+
- Adds the ability to automatically parse and replace HTML tags from some elements of the RSS feed
6+
37
## [0.7.2](https://pub.dev/packages/webfeed-revised/versions/0.7.2)
48
- Applied dart format
59

README.md

+8-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ Forked from [WebFeed - V0.7.0](https://pub.dev/packages/webfeed) and improved up
2020

2121
Add this line into your `pubspec.yaml`
2222
```
23-
webfeed_revised: ^0.7.2
23+
webfeed_revised: ^0.7.3
2424
```
2525

2626
Import the package into your dart code using:
@@ -30,12 +30,18 @@ import 'package:webfeed_revised/webfeed_revised.dart';
3030

3131
### Example
3232

33-
To parse string into `RssFeed` object use:
33+
To parse string into `RssFeed` object, use:
3434
```
3535
var rssFeed = RssFeed.parse(xmlString); // for parsing RSS feed
3636
var atomFeed = AtomFeed.parse(xmlString); // for parsing Atom feed
3737
```
3838

39+
To parse string into `RssFeed` object without automatic HTML parsing, use:
40+
```
41+
var rssFeed = RssFeed.parse(xmlString, false); // for parsing RSS feed
42+
var atomFeed = AtomFeed.parse(xmlString, false); // for parsing Atom feed
43+
```
44+
3945
### Preview
4046

4147
**RSS**

lib/domain/atom_feed.dart

+16-6
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import 'package:webfeed_revised/domain/atom_link.dart';
55
import 'package:webfeed_revised/domain/atom_person.dart';
66
import 'package:webfeed_revised/util/datetime.dart';
77
import 'package:webfeed_revised/util/iterable.dart';
8+
import 'package:webfeed_revised/util/xml.dart';
89
import 'package:xml/xml.dart';
910

1011
/// Represents an Atom feed
@@ -28,7 +29,8 @@ class AtomFeed {
2829
});
2930

3031
/// Parse constructor for the AtomFeed class, used when 'parsing' a feed
31-
factory AtomFeed.parse(String xmlString) {
32+
/// If [parseHtml] is true, HTML tags will be parsed from the feed
33+
factory AtomFeed.parse(String xmlString, [bool parseHtml = true]) {
3234
final document = XmlDocument.parse(xmlString);
3335
final feedElement = document.findElements('feed').firstOrNull;
3436
if (feedElement == null) {
@@ -37,10 +39,15 @@ class AtomFeed {
3739

3840
return AtomFeed(
3941
id: feedElement.findElements('id').firstOrNull?.text,
40-
title: feedElement.findElements('title').firstOrNull?.text,
41-
updated:
42-
parseDateTime(feedElement.findElements('updated').firstOrNull?.text),
43-
items: feedElement.findElements('entry').map(AtomItem.parse).toList(),
42+
title:
43+
feedElement.findElements('title').firstOrNull?.parseText(parseHtml),
44+
updated: parseDateTime(
45+
feedElement.findElements('updated').firstOrNull?.text,
46+
),
47+
items: feedElement
48+
.findElements('entry')
49+
.map((item) => AtomItem.parse(item, parseHtml))
50+
.toList(),
4451
links: feedElement.findElements('link').map(AtomLink.parse).toList(),
4552
authors:
4653
feedElement.findElements('author').map(AtomPerson.parse).toList(),
@@ -57,7 +64,10 @@ class AtomFeed {
5764
icon: feedElement.findElements('icon').firstOrNull?.text,
5865
logo: feedElement.findElements('logo').firstOrNull?.text,
5966
rights: feedElement.findElements('rights').firstOrNull?.text,
60-
subtitle: feedElement.findElements('subtitle').firstOrNull?.text,
67+
subtitle: feedElement
68+
.findElements('subtitle')
69+
.firstOrNull
70+
?.parseText(parseHtml),
6171
);
6272
}
6373

lib/domain/atom_item.dart

+8-5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import 'package:webfeed_revised/domain/atom_source.dart';
55
import 'package:webfeed_revised/domain/media/media.dart';
66
import 'package:webfeed_revised/util/datetime.dart';
77
import 'package:webfeed_revised/util/iterable.dart';
8+
import 'package:webfeed_revised/util/xml.dart';
89
import 'package:xml/xml.dart';
910

1011
/// Represents an Atom item
@@ -28,9 +29,9 @@ class AtomItem {
2829
});
2930

3031
/// Parse constructor for the AtomItem class, used when 'parsing' a feed
31-
factory AtomItem.parse(XmlElement element) => AtomItem(
32+
factory AtomItem.parse(XmlElement element, bool parseHtml) => AtomItem(
3233
id: element.findElements('id').firstOrNull?.text,
33-
title: element.findElements('title').firstOrNull?.text,
34+
title: element.findElements('title').firstOrNull?.parseText(parseHtml),
3435
updated:
3536
parseDateTime(element.findElements('updated').firstOrNull?.text),
3637
authors: element.findElements('author').map(AtomPerson.parse).toList(),
@@ -42,10 +43,12 @@ class AtomItem {
4243
source:
4344
element.findElements('source').map(AtomSource.parse).firstOrNull,
4445
published: element.findElements('published').firstOrNull?.text,
45-
content: element.findElements('content').firstOrNull?.text,
46-
summary: element.findElements('summary').firstOrNull?.text,
46+
content:
47+
element.findElements('content').firstOrNull?.parseText(parseHtml),
48+
summary:
49+
element.findElements('summary').firstOrNull?.parseText(parseHtml),
4750
rights: element.findElements('rights').firstOrNull?.text,
48-
media: Media.parse(element),
51+
media: Media.parse(element, parseHtml),
4952
);
5053

5154
/// The item id

lib/domain/dublin_core/dublin_core.dart

+18-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import 'package:webfeed_revised/util/datetime.dart';
22
import 'package:webfeed_revised/util/iterable.dart';
3+
import 'package:webfeed_revised/util/xml.dart';
34
import 'package:xml/xml.dart';
45

56
/// The Dublin Core Metadata Element Set
@@ -27,16 +28,26 @@ class DublinCore {
2728
});
2829

2930
/// Parse constructor for the DublinCore class, used when 'parsing' a feed
30-
factory DublinCore.parse(XmlElement element) => DublinCore(
31-
title: element.findElements('dc:title').firstOrNull?.text,
32-
description: element.findElements('dc:description').firstOrNull?.text,
31+
factory DublinCore.parse(XmlElement element, bool parseHtml) => DublinCore(
32+
title:
33+
element.findElements('dc:title').firstOrNull?.parseText(parseHtml),
34+
description: element
35+
.findElements('dc:description')
36+
.firstOrNull
37+
?.parseText(parseHtml),
3338
creator: element.findElements('dc:creator').firstOrNull?.text,
34-
subject: element.findElements('dc:subject').firstOrNull?.text,
39+
subject: element
40+
.findElements('dc:subject')
41+
.firstOrNull
42+
?.parseText(parseHtml),
3543
publisher: element.findElements('dc:publisher').firstOrNull?.text,
3644
contributor: element.findElements('dc:contributor').firstOrNull?.text,
37-
date: parseDateTime(element.findElements('dc:date').firstOrNull?.text),
38-
created:
39-
parseDateTime(element.findElements('dc:created').firstOrNull?.text),
45+
date: parseDateTime(
46+
element.findElements('dc:date').firstOrNull?.text,
47+
),
48+
created: parseDateTime(
49+
element.findElements('dc:created').firstOrNull?.text,
50+
),
4051
modified: parseDateTime(
4152
element.findElements('dc:modified').firstOrNull?.text,
4253
),

lib/domain/itunes/itunes.dart

+13-4
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class Itunes {
3232
});
3333

3434
/// Parse constructor for the Itunes class, used when 'parsing' a feed
35-
factory Itunes.parse(XmlElement element) {
35+
factory Itunes.parse(XmlElement element, bool parseHtml) {
3636
final episodeStr =
3737
element.findElements('itunes:episode').firstOrNull?.text ?? '';
3838
final seasonStr =
@@ -41,10 +41,19 @@ class Itunes {
4141
element.findElements('itunes:duration').firstOrNull?.text ?? '';
4242
return Itunes(
4343
author: element.findElements('itunes:author').firstOrNull?.text,
44-
summary: element.findElements('itunes:summary').firstOrNull?.text,
44+
summary: element
45+
.findElements('itunes:summary')
46+
.firstOrNull
47+
?.parseText(parseHtml),
4548
explicit: parseBoolLiteral(element, 'itunes:explicit'),
46-
title: element.findElements('itunes:title').firstOrNull?.text,
47-
subtitle: element.findElements('itunes:subtitle').firstOrNull?.text,
49+
title: element
50+
.findElements('itunes:title')
51+
.firstOrNull
52+
?.parseText(parseHtml),
53+
subtitle: element
54+
.findElements('itunes:subtitle')
55+
.firstOrNull
56+
?.parseText(parseHtml),
4857
owner: element
4958
.findElements('itunes:owner')
5059
.map(ItunesOwner.parse)

lib/domain/media/media.dart

+11-7
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ class Media {
5656
});
5757

5858
/// Parse constructor for the Media class, used when 'parsing' a feed
59-
factory Media.parse(XmlElement element) => Media(
59+
factory Media.parse(XmlElement element, bool parseHtml) => Media(
6060
group: element.findElements('media:group').map(Group.parse).firstOrNull,
6161
contents:
6262
element.findElements('media:content').map(Content.parse).toList(),
@@ -68,8 +68,9 @@ class Media {
6868
.firstOrNull,
6969
rating:
7070
element.findElements('media:rating').map(Rating.parse).firstOrNull,
71-
title:
72-
findElements(element, 'media:title')?.map(Title.parse).firstOrNull,
71+
title: findElements(element, 'media:title')
72+
?.map((title) => Title.parse(title, parseHtml))
73+
.firstOrNull,
7374
description: element
7475
.findElements('media:description')
7576
.map(Description.parse)
@@ -86,7 +87,10 @@ class Media {
8687
.findElements('media:copyright')
8788
.map(Copyright.parse)
8889
.firstOrNull,
89-
text: element.findElements('media:text').map(Text.parse).firstOrNull,
90+
text: element
91+
.findElements('media:text')
92+
.map((text) => Text.parse(text, parseHtml))
93+
.firstOrNull,
9094
restriction: element
9195
.findElements('media:restriction')
9296
.map(Restriction.parse)
@@ -99,15 +103,15 @@ class Media {
99103
.findElements('media:comments')
100104
.firstOrNull
101105
?.findElements('media:comment')
102-
.map((e) => e.text)
106+
.map((e) => e.parseText(parseHtml))
103107
.toList() ??
104108
[],
105109
embed: element.findElements('media:embed').map(Embed.parse).firstOrNull,
106110
responses: element
107111
.findElements('media:responses')
108112
.firstOrNull
109113
?.findElements('media:response')
110-
.map((e) => e.text)
114+
.map((e) => e.parseText(parseHtml))
111115
.toList() ??
112116
[],
113117
backLinks: element
@@ -134,7 +138,7 @@ class Media {
134138
.findElements('media:scenes')
135139
.firstOrNull
136140
?.findElements('media:scene')
137-
.map(Scene.parse)
141+
.map((item) => Scene.parse(item, parseHtml))
138142
.toList() ??
139143
[],
140144
);

lib/domain/media/scene.dart

+10-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import 'package:webfeed_revised/util/iterable.dart';
2+
import 'package:webfeed_revised/util/xml.dart';
23
import 'package:xml/xml.dart';
34

45
/// Used to specify a scene of a media element
@@ -13,9 +14,15 @@ class Scene {
1314
});
1415

1516
/// Parse constructor for the Scene class, used when 'parsing' a feed
16-
factory Scene.parse(XmlElement element) => Scene(
17-
title: element.findElements('sceneTitle').firstOrNull?.text,
18-
description: element.findElements('sceneDescription').firstOrNull?.text,
17+
factory Scene.parse(XmlElement element, bool parseHtml) => Scene(
18+
title: element
19+
.findElements('sceneTitle')
20+
.firstOrNull
21+
?.parseText(parseHtml),
22+
description: element
23+
.findElements('sceneDescription')
24+
.firstOrNull
25+
?.parseText(parseHtml),
1926
startTime: element.findElements('sceneStartTime').firstOrNull?.text,
2027
endTime: element.findElements('sceneEndTime').firstOrNull?.text,
2128
);

lib/domain/media/text.dart

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import 'package:webfeed_revised/util/xml.dart';
12
import 'package:xml/xml.dart';
23

34
/// The text of a media element
@@ -13,12 +14,12 @@ class Text {
1314
});
1415

1516
/// Parse constructor for the Text class, used when 'parsing' a feed
16-
factory Text.parse(XmlElement element) => Text(
17+
factory Text.parse(XmlElement element, bool parseHtml) => Text(
1718
type: element.getAttribute('type'),
1819
lang: element.getAttribute('lang'),
1920
start: element.getAttribute('start'),
2021
end: element.getAttribute('end'),
21-
value: element.text,
22+
value: element.parseText(parseHtml),
2223
);
2324

2425
/// The type of the text

lib/domain/media/title.dart

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import 'package:webfeed_revised/util/xml.dart';
12
import 'package:xml/xml.dart';
23

34
/// The title of a media element
@@ -10,9 +11,9 @@ class Title {
1011
});
1112

1213
/// Parse constructor for the Title class, used when 'parsing' a feed
13-
factory Title.parse(XmlElement element) => Title(
14+
factory Title.parse(XmlElement element, bool parseHtml) => Title(
1415
type: element.getAttribute('type'),
15-
value: element.text,
16+
value: element.parseText(parseHtml),
1617
);
1718

1819
/// The type of the title

lib/domain/rss_feed.dart

+15-7
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import 'package:webfeed_revised/domain/rss_image.dart';
88
import 'package:webfeed_revised/domain/rss_item.dart';
99
import 'package:webfeed_revised/domain/syndication/syndication.dart';
1010
import 'package:webfeed_revised/util/iterable.dart';
11+
import 'package:webfeed_revised/util/xml.dart';
1112
import 'package:xml/xml.dart';
1213

1314
/// Represents an RSS feed
@@ -40,7 +41,8 @@ class RssFeed {
4041
});
4142

4243
/// Parse constructor for the RssFeed class, used when 'parsing' a feed
43-
factory RssFeed.parse(String xmlString) {
44+
/// If [parseHtml] is true, HTML tags will be parsed from the feed
45+
factory RssFeed.parse(String xmlString, [bool parseHtml = true]) {
4446
final document = XmlDocument.parse(xmlString);
4547
final rss = document.findElements('rss').firstOrNull;
4648
final rdf = document.findElements('rdf:RDF').firstOrNull;
@@ -52,17 +54,23 @@ class RssFeed {
5254
throw ArgumentError('channel not found');
5355
}
5456
return RssFeed(
55-
title: channelElement.findElements('title').firstOrNull?.text,
57+
title: channelElement
58+
.findElements('title')
59+
.firstOrNull
60+
?.parseText(parseHtml),
5661
author: channelElement.findElements('author').firstOrNull?.text,
57-
description: channelElement.findElements('description').firstOrNull?.text,
62+
description: channelElement
63+
.findElements('description')
64+
.firstOrNull
65+
?.parseText(parseHtml),
5866
link: channelElement.findElements('link').firstOrNull?.text,
5967
items: (rdf ?? channelElement)
6068
.findElements('item')
61-
.map(RssItem.parse)
69+
.map((item) => RssItem.parse(item, parseHtml))
6270
.toList(),
6371
image: (rdf ?? channelElement)
6472
.findElements('image')
65-
.map(RssImage.parse)
73+
.map((image) => RssImage.parse(image, parseHtml))
6674
.firstOrNull,
6775
cloud:
6876
channelElement.findElements('cloud').map(RssCloud.parse).firstOrNull,
@@ -97,8 +105,8 @@ class RssFeed {
97105
ttl: int.tryParse(
98106
channelElement.findElements('ttl').firstOrNull?.text ?? '0',
99107
),
100-
dc: DublinCore.parse(channelElement),
101-
itunes: Itunes.parse(channelElement),
108+
dc: DublinCore.parse(channelElement, parseHtml),
109+
itunes: Itunes.parse(channelElement, parseHtml),
102110
syndication: Syndication.parse(channelElement),
103111
);
104112
}

lib/domain/rss_image.dart

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import 'package:webfeed_revised/util/iterable.dart';
2+
import 'package:webfeed_revised/util/xml.dart';
23
import 'package:xml/xml.dart';
34

45
/// The image of a RSS feed
@@ -8,8 +9,8 @@ class RssImage {
89
RssImage({this.title, this.url, this.link});
910

1011
/// Parse constructor for the RssImage class, used when 'parsing' a feed
11-
factory RssImage.parse(XmlElement element) => RssImage(
12-
title: element.findElements('title').firstOrNull?.text,
12+
factory RssImage.parse(XmlElement element, bool parseHtml) => RssImage(
13+
title: element.findElements('title').firstOrNull?.parseText(parseHtml),
1314
url: element.findElements('url').firstOrNull?.text,
1415
link: element.findElements('link').firstOrNull?.text,
1516
);

0 commit comments

Comments
 (0)