Manipulating XML
The XML data type supports manipulation of XML attributes and child elements.
Attributes
Checking for Attributes in XML
import static org.camunda.spin.Spin.XML;
String xml = "<order xmlns:cam=\"http://camunda.org/example\" id=\"order1\" cam:name=\"name\" />";
boolean hasAttr = XML(xml).hasAttr("id");
assertTrue(hasAttr);
hasAttr = XML(xml).hasAttrNs("http://camunda.org/example", "id");
assertTrue(hasAttr);
Reading Attributes from XML
import static org.camunda.spin.Spin.XML;
SpinXmlDomAttribute attribute = XML("<order id=\"order1\" />").attr("id");
String id = XML("<order id=\"order1\" />").attr("id").value();
The attr
method returns a wrapper of the XML attribute and with value
the value of the attribute can be accessed.
If you want to access an attribute in another namespace you have to use the attrNs
method.
import static org.camunda.spin.Spin.XML;
String xml = "<order xmlns:cam=\"http://camunda.org/example\" id=\"order1\" cam:name=\"order1\" />";
SpinXmlDomAttribute attribute = XML(xml).attrNs("http://camunda.org/example", "name");
You can also get a collection of all attributes or only of a specific namespace.
import static org.camunda.spin.Spin.XML;
String xml = "<order xmlns:cam=\"http://camunda.org/example\" id=\"order1\" cam:name=\"order1\" />";
// All attributes
SpinCollection<SpinXmlDomAttribute> attributes = XML(xml).attrs();
// All attributes of a specific namespace
attributes = XML(xml).attrs("http://camunda.org/example");
Or you can directly get all attribute names instead.
import static org.camunda.spin.Spin.XML;
String xml = "<order xmlns:cam=\"http://camunda.org/example\" id=\"order1\" cam:name=\"order1\" />";
// All attribute names
List<String> names = XML(xml).attrNames();
// All attribute names of a specific namespace
names = XML(xml).attrNames("http://camunda.org/example");
Writing Attributes to XML
It is possible to set a new attribute value directly from the element wrapper or on the attribute wrapper.
import static org.camunda.spin.Spin.XML;
String xml = "<order id=\"order1\" />";
XML(xml).attr("id", "newId");
SpinXmlDomAttribute attribute = XML(xml).attr("id");
attribute.value("newId");
You can also specify the namespace of the attribute to set.
import static org.camunda.spin.Spin.XML;
String xml = "<order xmlns:cam=\"http://camunda.org/example\" id=\"order1\" cam:name=\"name\" />";
XML(xml).attrNs("http://camunda.org/example", "name", "newName");
SpinXmlDomAttribute attribute = XML(xml).attrNs("http://camunda.org/example", "name");
attribute.value("newName");
Removing Attributes from XML
It is possible to remove an attribute from the element directly or to remove the attribute itself.
import static org.camunda.spin.Spin.XML;
String xml = "<order id=\"order1\" />";
SpinXmlDomElement element = XML(xml).removeAttr("id");
assertFalse(element.hasAttr("id));
SpinXmlDomAttribute attribute = XML(xml).attr("id");
element = attribute.remove();
assertFalse(element.hasAttr("id));
You can also specify the namespace of the attribute to remove.
import static org.camunda.spin.Spin.XML;
String xml = "<order xmlns:cam=\"http://camunda.org/example\" id=\"order1\" cam:name=\"name\" />";
SpinXmlDomElement element = XML(xml).removeAttrNs("http://camunda.org/example", "name");
assertFalse(element.hasAttrNs("http://camunda.org/example/", "name"));
SpinXmlDomAttribute attribute = XML(xml).attrNs("http://camunda.org/example", "name");
element = attribute.remove()
assertFalse(element.hasAttrNs("http://camunda.org/example", "name"));
Text Content
It is possible to read and write the text content of an XML element with the textContent
method.
import static org.camunda.spin.Spin.XML;
SpinXmlDomElement element = XML("<customer>Foo</customer>");
assertEquals("Foo", element.textContent());
element.textContent("Bar");
Child Elements
Reading Child Elements from XML
Besides attributes you can also get a unique or all child elements of a specific type. Optionally, a namespace can be passed to the methods as first parameter.
import static org.camunda.spin.Spin.XML;
String xml = "<order xmlns:cam=\"http://camunda.org/example\">" +
"<date/><cam:due/><item/><item/><cam:op/><cam:op/></order>";
SpinXmlDomElement date = XML(xml).childElement("date");
SpinXmlDomElement due = XML(xml).childElement("http://camunda.org/example", "due");
SpinCollection<SpinXmlDomElement> items = XML(xml).childElements("item");
SpinCollection<SpinXmlDomElement> ops = XML(xml).childElements("http://camunda.org/example", "ops");
Append Child Elements
The method append
is used to append a single or multiple child elements to an XML element.
import static org.camunda.spin.Spin.XML;
SpinXmlTreeElement root = XML("<root/>");
SpinXmlTreeElement child1 = XML("<child/>");
SpinXmlTreeElement child2 = XML("<child/>");
SpinXmlTreeElement child3 = XML("<child/>");
root.append(child1, child2, child3);
Remove Child Elements
To remove child elements from an XML element the method remove
is used. It accepts single or multiple child elements and removes them from the parent element.
import static org.camunda.spin.Spin.XML;
SpinXmlTreeElement root = XML("<root><child/><child/><child/></root>");
root.remove(root.childElements("child"));
Replace Elements
To replace an element or a child element the methods replace
and replaceChild
are used.
import static org.camunda.spin.Spin.XML;
SpinXmlTreeElement root = XML("<root><date/><order/></root>");
SpinXmlTreeElement child1 = XML("<child/>");
root.replaceChild(root.childElement("date"), child1);
SpinXmlTreeElement child2 = XML("<child/>");
root.childElement("order").replace(child2);
Manipulating XML using a Script Language
XML can be manipulated from script languages in the same was as from Java. Since script languages use dynamic typing, you do not need to hint the data format but you can use autodetection. The following example demonstrates how to access an attribute and a child element from XML in Python:
xml = """
<order id="1231">
<item id="1"/>
</order>
"""
assert S(xml).hasAttr('id')
order_id = S(xml).attr('id').value()
assert order_id == '1231'
element = S(xml).attr('order', 'order1')
assert element.hasAttr('order')
assert element.Attr('order').value() == 'order1'
element.removeAttr('order')
assert not element.hasAttr('order')
item_id = S(xml).childElement('item').attr('id').value()
assert item_id == '1'