/** * Returns the value associated to an attribute as a string or a default value. * * @param name The attribute name. * @param def The value to return if no attribute named {@code name} exists. * @return The value of attribute named {@code name} or {@code def}. */ public String getAttributeValue(String name, String def) { return getAttributeValue(name, def, FailureReaction.DEFAULT); }
@Override public Element clone(boolean recurse) { final Element result = new Element(this); if (recurse) { for (final Child child : getChildren()) { result.addChild(child.clone(true)); } } return result; }
/** * Creates an element by cloning another one. * <p> * Cloning is shallow.<br> * For deep cloning, use {@link #clone(boolean)}. * * @param other The element to clone. */ public Element(Element other) { this(null, other.getName()); for (int index = 0; index < other.getAttributesCount(); index++) { addAttribute(new Attribute(other.getAttributeAt(index))); } }
@Override public String toString() { final StringBuilder builder = new StringBuilder(); builder.append("[" + getType() + " " + getName()); for (final Attribute att : getAttributes()) { builder.append(" " + att.getName() + "='" + att.getValue() + "'"); } builder.append("]"); return builder.toString(); }
@Test public void testGetChildren() { final Element root = new Element(NAME); assertEquals(null, root.getLastChild()); final Element child1 = root.addElement(NAME1); final Element child2 = root.addElement(NAME2); final Element child3 = root.addElement(NAME1); child3.addAttribute(NAME, VALUE); final Comment child4 = root.addComment("Hello"); assertEquals(4, root.getChildrenCount()); assertTrue(root.hasChildren(Element.class)); assertTrue(root.hasChildren(Comment.class)); assertFalse(root.hasChildren(Text.class)); assertEquals(child4, root.getLastChild()); assertEquals(child1, root.getChild(Element.class)); assertEquals(child1, root.getElementNamed(NAME1)); assertEquals(3, root.getChildrenCount(Element.class)); assertEquals(2, root.getChildrenCount(Element.class, Element.named(NAME1))); assertEquals(child2, root.getChild(Element.class, Element.named(NAME2))); assertEquals(child2, root.getChildAt(Element.class, Element.named(NAME2), 0)); assertEquals(null, root.getChildAt(Element.class, Element.named(NAME2), 1)); assertEquals(child3, root.getChildAt(2)); assertEquals(child3, root.getChildAt(Element.class, 2)); assertEquals(child4, root.getChildAt(Comment.class, 0)); assertEquals(3, Iterables.size(root.getElements())); assertEquals(1, Iterables.size(root.getComments())); assertEquals(0, Iterables.size(root.getTexts())); assertEquals(child3, root.getElementNamedWithAttribute(NAME1, NAME, VALUE)); }
@Test public void testAttributes() { final Element e = new Element(NAME); assertEquals(0, e.getAttributesCount()); assertFalse(e.hasAttribute(NAME1)); assertEquals(-1, e.getAttributeIndex(NAME1)); assertTrue(e.getAttributes().isEmpty()); assertEquals(null, e.getAttributeValue(NAME1)); e.addAttribute(NAME1, null); assertTrue(e.hasAttribute(NAME1)); assertEquals(null, e.getAttributeValue(NAME1)); assertEquals(0, e.getAttributeIndex(NAME1)); assertEquals(-1, e.getAttributeIndex(NAME2)); assertFalse(e.hasAttribute(NAME2)); assertEquals(1, e.getAttributes().size()); assertEquals(Boolean.TRUE, e.getAttributeAsOptionalBoolean(NAME1, Boolean.TRUE)); assertEquals(Long.valueOf(0L), e.getAttributeAsOptionalLong(NAME1, 0L)); assertEquals(Integer.valueOf(0), e.getAttributeAsOptionalInt(NAME1, 0)); assertEquals(Short.valueOf((short) 0), e.getAttributeAsOptionalShort(NAME1, (short) 0)); assertEquals(Byte.valueOf((byte) 0), e.getAttributeAsOptionalByte(NAME1, (byte) 0)); assertEquals(Double.valueOf(0.0), e.getAttributeAsOptionalDouble(NAME1, 0.0)); assertEquals(Float.valueOf(0.0F), e.getAttributeAsOptionalFloat(NAME1, 0.0F)); assertEquals(FailureReaction.DEFAULT, e.getAttributeAsOptionalEnum(NAME1, FailureReaction.class, FailureReaction.DEFAULT)); }
@Test public void testGetText() { final Element e = new Element(NAME); assertEquals(null, e.getText()); e.addComment("Hello"); assertEquals(null, e.getText()); e.removeChildAt(0); assertEquals(null, e.getText()); e.addComment("Comment"); e.addText("Hello"); assertEquals("Hello", e.getText()); e.addText("World"); assertEquals("HelloWorld", e.getText()); e.addElement("Child"); assertEquals(null, e.getText()); e.removeChildren(); e.addText("Hello", false); e.addComment("Comment"); e.addText("World", false); assertEquals("HelloWorld", e.getText()); e.removeChildren(); e.addText("true"); assertEquals(true, e.getTextAsBoolean(false)); assertEquals(true, e.getTextAsOptionalBoolean(null)); e.removeChildren(); e.addText("10"); assertEquals(10L, e.getTextAsLong(0));
@Test public void testChangeTexts() { final Element root = new Element(NAME); root.addText("hello", false); root.addText("HELLO", false); root.changeTexts(String::toUpperCase); assertEquals(2, root.getChildrenCount()); assertEquals("HELLO", root.getChildAt(Text.class, 0).getContent()); assertEquals("HELLO", root.getChildAt(Text.class, 1).getContent()); root.removeChildren(); final Element child1 = root.addElement(NAME1); final Element child2 = root.addElement(NAME2); final Element child3 = root.addElement(NAME1); child1.addText("hello"); child2.addText("hello"); child3.addText("hel"); child3.addText("lo", false); assertEquals(2, child3.getChildrenCount()); root.changeTexts(String::toUpperCase); assertEquals(2, child3.getChildrenCount()); root.changeNamedTexts(NAME1, String::toUpperCase); assertEquals(1, child3.getChildrenCount()); assertEquals("HELLO", child1.getText()); assertEquals("HELLO", child3.getText()); }
@Test public void testRemoveChildren1() { final Element root = new Element(NAME); final Element child1 = root.addElement(NAME1); final Element child2 = root.addElement(NAME2); final Element child3 = root.addElement(NAME3); assertEquals(child1, root.getChildAt(0)); assertEquals(child2, root.getChildAt(1)); assertEquals(child3, root.getChildAt(2)); assertEquals(1, root.getChildrenCount(Element.class, Element.named(NAME1))); assertEquals(1, root.getChildrenCount(Element.class, Element.named(NAME2))); assertEquals(1, root.getChildrenCount(Element.class, Element.named(NAME3))); root.removeChildAt(0); assertEquals(child2, root.getChildAt(0)); assertEquals(child3, root.getChildAt(1)); assertEquals(0, root.getChildrenCount(Element.class, Element.named(NAME1))); assertEquals(1, root.getChildrenCount(Element.class, Element.named(NAME2))); assertEquals(1, root.getChildrenCount(Element.class, Element.named(NAME3))); root.removeChildAt(0); assertEquals(child3, root.getChildAt(0)); assertEquals(0, root.getChildrenCount(Element.class, Element.named(NAME1))); assertEquals(0, root.getChildrenCount(Element.class, Element.named(NAME2))); assertEquals(1, root.getChildrenCount(Element.class, Element.named(NAME3))); root.removeChildAt(0); root.addChild(child1); root.addChild(child2);
@Test public void testChildren() { final Element e = new Element(NAME); assertEquals(null, e.getDocument()); assertEquals(e, e.getRootElement()); assertEquals(e, e.getRootChild()); final Element c0 = e.addElement(NAME1); final Element c1 = e.addElement(NAME1); final Text c2 = e.addText("Hello"); final Comment c3 = e.addComment("Hello"); assertEquals(c0, e.getChildAt(0)); assertEquals(c1, e.getChildAt(1)); assertEquals(c0, e.getElementNamed(NAME1)); assertEquals(null, c2.getDocument()); assertEquals(e, c3.getRootElement()); assertEquals(e, c3.getRootChild()); assertEquals(e, c2.getParent()); assertEquals(e, c2.getParent(Element.class)); assertEquals(4, e.getChildrenCount()); assertEquals(4, e.getChildrenCount(Node.class)); assertEquals(2, e.getChildrenCount(Element.class)); assertEquals(1, e.getChildrenCount(Comment.class)); assertEquals(1, e.getChildrenCount(Text.class)); assertEquals(2, e.getChildrenCount(Parent.class)); assertEquals(4, e.getChildrenCount(Child.class)); assertEquals(2, e.getChildrenCount(Leaf.class)); }
@Test public void testRemoveChildren() { final Element root = new Element(NAME); final Element child = root.addElement(NAME); root.removeChildren(); assertEquals(0, root.getChildrenCount()); assertFalse(root.removeChild(child)); root.addElement(NAME); root.addComment("Hello"); root.addElement(NAME); root.addText("World"); root.addElement(NAME); root.removeComments(); assertEquals(4, root.getChildrenCount()); root.removeTexts(); assertEquals(3, root.getChildrenCount()); root.addElement(NAME1); root.removeElementsNamed(NAME); assertEquals(1, root.getChildrenCount()); }
@Test public void testMerge() { final Element root = new Element(NAME); root.addElement(NAME); root.addComment("Hello"); assertEquals(1, root.getChildrenCount(Comment.class)); root.addComment("World"); assertEquals(1, root.getChildrenCount(Comment.class)); root.addComment("Foo", false); assertEquals(2, root.getChildrenCount(Comment.class)); root.mergeComments(); assertEquals(1, root.getChildrenCount(Comment.class)); root.removeChildren(); root.addElement(NAME); root.addComment("Hello", false); root.addElement(NAME); root.addComment("Hello", false); root.addComment("Hello", false); root.addText("Hello", false); root.addComment("Hello", false); root.addComment("Hello", false); root.addText("Hello", false); root.addText("Hello", false); assertEquals(5, root.getChildrenCount(Comment.class)); assertEquals(3, root.getChildrenCount(Text.class)); root.mergeComments(); assertEquals(3, root.getChildrenCount(Comment.class)); assertEquals(3, root.getChildrenCount(Text.class));
@Test public void testChangeComments() { final Element root = new Element(NAME); root.addComment("hello", false); root.addComment("HELLO", false); root.changeComments(String::toUpperCase); assertEquals(2, root.getChildrenCount()); assertEquals("HELLO", root.getChildAt(Comment.class, 0).getContent()); assertEquals("HELLO", root.getChildAt(Comment.class, 1).getContent()); root.removeChildren(); final Element child1 = root.addElement(NAME1); final Element child2 = root.addElement(NAME2); final Element child3 = root.addElement(NAME1); child1.addComment("hello"); child2.addComment("hello"); child3.addComment("hel"); child3.addComment("lo", false); assertEquals(2, child3.getChildrenCount()); root.changeComments(String::toUpperCase, true); assertEquals(2, child3.getChildrenCount()); assertEquals("HELLO", child1.getChild(Comment.class).getContent()); assertEquals("HEL", child3.getChildAt(Comment.class, 0).getContent()); }
Function<String, String> modifier) { for (final Element child : getElementsNamed(name)) { switch (child.getContentType()) { case EMPTY: case TEXT: final String content = child.getText(); final String newContent = modifier.apply(content); if (Operators.notEquals(content, newContent)) { if (child.getChildrenCount(Text.class) == 1 && newContent != null && !newContent.isEmpty()) { final Text text = child.getChild(Text.class); text.clearContent(); text.appendContent(newContent); } else { child.removeChildren(); if (newContent != null && !newContent.isEmpty()) { child.addText(modifier.apply(content));
@Test public void testSortAttribute() { final Element root = new Element("root"); for (int i = 9; i >= 0; i--) { final Element child = root.addElement("child"); child.addAttribute("id", i); } assertEquals(root.getElementNamedWithAttribute("child", "id", "0"), root.getChildAt(9)); root.sortChildren(ComparatorsUtil.adapt(Element.class, Element.compareAttribute("id"))); assertEquals(root.getElementNamedWithAttribute("child", "id", "0"), root.getChildAt(0)); } }
@Test public void testContentType() { final Element e = new Element(NAME); assertEquals(ElementContentType.EMPTY, e.getContentType()); e.addComment("Hello"); assertEquals(ElementContentType.NON_TEXT, e.getContentType()); e.removeChildren(); assertEquals(ElementContentType.EMPTY, e.getContentType()); e.addText("Hello"); assertEquals(ElementContentType.TEXT, e.getContentType()); e.addText("World"); assertEquals(ElementContentType.TEXT, e.getContentType()); e.addComment("Hello"); assertEquals(ElementContentType.MIXED, e.getContentType()); e.removeChildren(); assertEquals(ElementContentType.EMPTY, e.getContentType()); e.addElement("child"); assertEquals(ElementContentType.NON_TEXT, e.getContentType()); e.addComment("Hello"); assertEquals(ElementContentType.NON_TEXT, e.getContentType()); e.addText("World"); assertEquals(ElementContentType.MIXED, e.getContentType()); }
@Test public void testSortName() { final Element root = new Element("root"); for (int i = 9; i >= 0; i--) { root.addElement("child-" + i); } assertEquals(root.getElementNamed("child-0"), root.getChildAt(9)); root.sortChildren(ComparatorsUtil.adapt(Element.class, Element.NAME_COMPARATOR)); assertEquals(root.getElementNamed("child-0"), root.getChildAt(0)); }
@Test public void testRemoveChildren() { final Element root = new Element(NAME); root.addElement(NAME1); root.addElement(NAME1); root.addElement(NAME2); root.addElement(NAME1); root.addElement(NAME1); assertEquals(5, root.getChildrenCount(Element.class)); assertEquals(4, root.getChildrenCount(Element.class, Element.named(NAME1))); root.removeChildAt(0); assertEquals(4, root.getChildrenCount(Element.class)); assertEquals(3, root.getChildrenCount(Element.class, Element.named(NAME1))); root.removeElementsNamed(NAME1); assertEquals(1, root.getChildrenCount(Element.class)); assertEquals(0, root.getChildrenCount(Element.class, Element.named(NAME1))); } }
public static void setContentOfMatchingElements(Parent parent, ElementPredicate predicate, TextContentConverter converter, Evaluator<? super Parent> evaluator) { if (parent instanceof Element) { final Element element = (Element) parent; if (predicate.accepts(element.getParent(), element)) { final int count = element.getChildrenCount(); if (count == 0) { // Add a text child final String content = converter.convertTextContent(element, null); if (content != null) { element.addText(content); } } else if (count == 1 && element.hasOnlyText()) { // Modify text child if possible final Text text = element.getChild(Text.class); final String content = converter.convertTextContent(element, text.getContent()); text.setContent(content); } } } for (final Child child : parent.getChildren()) { if (child instanceof Parent && evaluator.evaluate((Parent) child) == Evaluation.CONTINUE) { setContentOfMatchingElements((Parent) child, predicate, converter, evaluator); } } }
/** * Returns a comparator that compares the names then the values of a particular attribute. * * @param attributeName The name of the attribute to use. * @return A comparator that compares the names then the values of attributes named {@code attributeName}. */ public static Comparator<Element> compareNameAndAttribute(String attributeName) { return (o1, o2) -> { final String name1 = o1 == null ? null : o1.getName(); final String name2 = o2 == null ? null : o2.getName(); final int nameCmp = Operators.compare(name1, name2); if (nameCmp == 0) { final String value1 = o1.getAttributeValue(attributeName, null, FailureReaction.WARN); final String value2 = o2.getAttributeValue(attributeName, null, FailureReaction.WARN); return Operators.compare(value1, value2); } else { return nameCmp; } }; }