diff --git a/src/main/java/org/jsoup/nodes/Element.java b/src/main/java/org/jsoup/nodes/Element.java index fa541d5661..7b83891985 100644 --- a/src/main/java/org/jsoup/nodes/Element.java +++ b/src/main/java/org/jsoup/nodes/Element.java @@ -86,6 +86,36 @@ public Element(Tag tag, @Nullable String baseUri) { this(tag, baseUri, null); } + private Element() { + this("-"); + } + + /** + * Parse HTML String into an Element + *

+ * Use examples: + *

+ *

+ * @param html HTML to parse + * @return an Element + */ + public static Element parse(String html) { + Element dummyElement = new Element().html(html); + if (dummyElement.childNodeSize() > 1) { + throw new IllegalArgumentException("Element syntax error: Number of outer element must be one"); + } + if (dummyElement.childNodeSize() == 0) { + throw new IllegalArgumentException("Element syntax error: No legal element detected"); + } + Element e = dummyElement.child(0); + e.parentNode = null; + return e; + } + /** Internal test to check if a nodelist object has been created. */ diff --git a/src/test/java/org/jsoup/nodes/ElementTest.java b/src/test/java/org/jsoup/nodes/ElementTest.java index 563442bd04..e179feebd0 100644 --- a/src/test/java/org/jsoup/nodes/ElementTest.java +++ b/src/test/java/org/jsoup/nodes/ElementTest.java @@ -729,7 +729,7 @@ public void testWrapNoop() { @Test public void testWrapOnOrphan() { - Element orphan = new Element("span").text("Hello!"); + Element orphan = Element.parse("Hello!"); assertFalse(orphan.hasParent()); Element wrapped = orphan.wrap("
There!"); assertSame(orphan, wrapped); @@ -1445,8 +1445,8 @@ public void testShadowElementsAreUpdated() { assertEquals(2, els.size()); // the two Ps assertEquals(3, nodes.size()); // the "Three" textnode - Element p3 = new Element("p").text("P3"); - Element p4 = new Element("p").text("P4"); + Element p3 = Element.parse("

P3

"); + Element p4 = Element.parse("

P4

"); div.insertChildren(1, p3); div.insertChildren(3, p4); Elements els2 = div.children(); @@ -1839,8 +1839,8 @@ public void doesntDeleteZWJWhenNormalizingText() { public void testReparentSeperateNodes() { String html = "

One

Two"; Document doc = Jsoup.parse(html); - Element new1 = new Element("p").text("Three"); - Element new2 = new Element("p").text("Four"); + Element new1 = Element.parse("

Three

"); + Element new2 = Element.parse("

Four

"); doc.body().insertChildren(-1, new1, new2); assertEquals("

One

Two

Three

Four

", TextUtil.stripNewlines(doc.body().html())); @@ -1863,14 +1863,14 @@ public void testNotActuallyAReparent() { String html = "
"; Document doc = Jsoup.parse(html); Element div = doc.selectFirst("div"); - Element new1 = new Element("p").text("One"); - Element new2 = new Element("p").text("Two"); + Element new1 = Element.parse("

One

"); + Element new2 = Element.parse("

Two

"); div.addChildren(new1, new2); assertEquals("

One

Two

", TextUtil.stripNewlines(div.outerHtml())); // and the issue setup: - Element new3 = new Element("p").text("Three"); + Element new3 = Element.parse("

Three

"); Element wrap = new Element("nav"); wrap.addChildren(0, new1, new3); @@ -2099,4 +2099,21 @@ public void childNodesAccessorDoesNotVivify() { p.removeAttr("foo"); assertEquals(0, p.attributesSize()); } + + @Test void parseFromHtmlOneElementSuccess() { + Element e = Element.parse("
test
"); + assertEquals(e.tagName(), "div"); + assertEquals(e.child(0).tagName(), "text"); + assertEquals(e.child(0).text(), "test"); + } + + @Test void parseFromHtmlMultiElementsError() { + Throwable exception = assertThrows(IllegalArgumentException.class, () -> Element.parse("
  • item1
  • item2
  • ")); + assertEquals("Element syntax error: Number of outer element must be one", exception.getMessage()); + } + + @Test void parseFromHtmlNoElementError() { + Throwable exception = assertThrows(IllegalArgumentException.class, () -> Element.parse("")); + assertEquals("Element syntax error: No legal element detected", exception.getMessage()); + } }