On using StreamParser.parse(), it is found that hrefs links are duplicated , whereas using Jsoup.parse() returns the expected document. Is there any reason why StreamParser would create additional references to href?
Is this expected behaviour when using a StreamParser?
String s1= "<!DOCTYPE html>\n"
+ "<html>\n"
+ "<head>\n"
+ " <title></title>\n"
+ "</head>\n"
+ "<body>\n"
+ " <a href=\"/:x:/g/gibberishtext\">Some link</a>\n"
+ "</body>\n"
+ "</html>";
StreamParser streamParser = new StreamParser(Parser.htmlParser());
StreamParser parse = streamParser.parse(s1, "");
parse.stream().forEach(System.out::println);
// Output from StreamParser, Returns five references to href
<title></title>
<head>
<title></title>
</head>
<a href="/:x:/g/gibberishtext">Some link</a>
<body>
<a href="/:x:/g/gibberishtext">Some link</a>
</body>
<a href="/:x:/g/gibberishtext">Some link</a>
<body>
<a href="/:x:/g/gibberishtext">Some link</a>
</body>
<html>
<head>
<title></title>
</head>
<body>
<a href="/:x:/g/gibberishtext">Some link</a>
</body>
</html>
<!doctype html>
<html>
<head>
<title></title>
</head>
<body>
<a href="/:x:/g/gibberishtext">Some link</a>
</body>
</html>
Whereas using Jsoup.parse() returns the expected document
Document parse1 = Jsoup.parse(s1);
System.out.println(parse1.toString());
//Output from using Jsoup 1.19.1
<!doctype html>
<html>
<head>
<title></title>
</head>
<body>
<a href="/:x:/g/gibberishtext">Some link</a>
</body>
</html>
Further update....
Now to make it more interesting..
If I call Jsoup.parse(s1).stream().forEach(System.out::println) it gives the result similar to StreamParser.
Why calling stream() is causing duplication?
On using StreamParser.parse(), it is found that hrefs links are duplicated , whereas using Jsoup.parse() returns the expected document. Is there any reason why StreamParser would create additional references to href?
Is this expected behaviour when using a StreamParser?
String s1= "<!DOCTYPE html>\n"
+ "<html>\n"
+ "<head>\n"
+ " <title></title>\n"
+ "</head>\n"
+ "<body>\n"
+ " <a href=\"https://fake/:x:/g/gibberishtext\">Some link</a>\n"
+ "</body>\n"
+ "</html>";
StreamParser streamParser = new StreamParser(Parser.htmlParser());
StreamParser parse = streamParser.parse(s1, "");
parse.stream().forEach(System.out::println);
// Output from StreamParser, Returns five references to href
<title></title>
<head>
<title></title>
</head>
<a href="https://fake/:x:/g/gibberishtext">Some link</a>
<body>
<a href="https://fake/:x:/g/gibberishtext">Some link</a>
</body>
<a href="https://fake/:x:/g/gibberishtext">Some link</a>
<body>
<a href="https://fake/:x:/g/gibberishtext">Some link</a>
</body>
<html>
<head>
<title></title>
</head>
<body>
<a href="https://fake/:x:/g/gibberishtext">Some link</a>
</body>
</html>
<!doctype html>
<html>
<head>
<title></title>
</head>
<body>
<a href="https://fake/:x:/g/gibberishtext">Some link</a>
</body>
</html>
Whereas using Jsoup.parse() returns the expected document
Document parse1 = Jsoup.parse(s1);
System.out.println(parse1.toString());
//Output from using Jsoup 1.19.1
<!doctype html>
<html>
<head>
<title></title>
</head>
<body>
<a href="https://fake/:x:/g/gibberishtext">Some link</a>
</body>
</html>
Further update....
Now to make it more interesting..
If I call Jsoup.parse(s1).stream().forEach(System.out::println) it gives the result similar to StreamParser.
Why calling stream() is causing duplication?
Share Improve this question edited 2 days ago Gee asked 2 days ago GeeGee 4795 silver badges14 bronze badges1 Answer
Reset to default 1That's an interesting question! There are in fact two kinds of duplications going on.
1st Duplication
First of, when you print an element, you also print all of its children. That makes your output a bit verbose. Perhaps it'd be more prudent to replace:
parse.stream().forEach(System.out::println);
with something like:
parse.stream().forEach(el -> System.out.println(el.tagName()));
to only print element tags.
2nd Duplication
Fixing 1, you'd then observe the following output:
title
head
a
body
a
body
html
#root
There's still some duplication but not nearly as much. Let's first focus on the output order. With StreamParser
...
Elements are emitted as they are completed... [Source]
This means that whenever a full element is parsed, it will be emitted. It's easy to check that title
is the first element that's fully parsed.
However, the following sequence:
a
body
appearing twice in the output seems wrong. One would expect only one occurrence. I can't say whether that's intended behavior or a bug.
But if I replace:
StreamParser streamParser = new StreamParser(Parser.htmlParser());
with:
StreamParser streamParser = new StreamParser(Parser.xmlParser());
I get the output I'd expect:
title
head
a
body
html
#root