Skip to content

Commit e7c98a9

Browse files
committed
Merge from remote
1 parent 7e8ba52 commit e7c98a9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1514
-0
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package com.baeldung.xml;
2+
3+
import org.w3c.dom.Document;
4+
5+
import javax.xml.transform.*;
6+
import javax.xml.transform.dom.DOMSource;
7+
import javax.xml.transform.stream.StreamResult;
8+
import java.io.File;
9+
import java.io.FileWriter;
10+
import java.io.IOException;
11+
12+
public class XMLDocumentWriter {
13+
14+
public void write(Document document, String fileName, boolean excludeDeclaration, boolean prettyPrint) {
15+
try(FileWriter writer = new FileWriter(new File(fileName))) {
16+
TransformerFactory transformerFactory = TransformerFactory.newInstance();
17+
Transformer transformer = transformerFactory.newTransformer();
18+
if(excludeDeclaration) {
19+
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
20+
}
21+
if(prettyPrint) {
22+
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
23+
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
24+
}
25+
DOMSource source = new DOMSource(document);
26+
StreamResult result = new StreamResult(writer);
27+
transformer.transform(source, result);
28+
} catch (IOException e) {
29+
throw new IllegalArgumentException(e);
30+
} catch (TransformerConfigurationException e) {
31+
throw new IllegalStateException(e);
32+
} catch (TransformerException e) {
33+
throw new IllegalArgumentException(e);
34+
}
35+
}
36+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package com.baeldung.xml.attribute;
2+
3+
import org.dom4j.*;
4+
import org.dom4j.io.DocumentSource;
5+
import org.dom4j.io.SAXReader;
6+
import org.xml.sax.SAXException;
7+
8+
import javax.xml.XMLConstants;
9+
import javax.xml.transform.OutputKeys;
10+
import javax.xml.transform.Transformer;
11+
import javax.xml.transform.TransformerException;
12+
import javax.xml.transform.TransformerFactory;
13+
import javax.xml.transform.stream.StreamResult;
14+
import java.io.StringWriter;
15+
import java.io.Writer;
16+
import java.util.List;
17+
18+
public class Dom4jTransformer {
19+
private final Document input;
20+
21+
public Dom4jTransformer(String resourcePath) throws DocumentException, SAXException {
22+
// 1- Build the doc from the XML file
23+
SAXReader xmlReader = new SAXReader();
24+
xmlReader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
25+
xmlReader.setFeature("http://xml.org/sax/features/external-general-entities", false);
26+
xmlReader.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
27+
this.input = xmlReader.read(resourcePath);
28+
}
29+
30+
public String modifyAttribute(String attribute, String oldValue, String newValue) throws TransformerException, TransformerException {
31+
// 2- Locate the node(s) with xpath, we can use index and iterator too.
32+
String expr = String.format("//*[contains(@%s, '%s')]", attribute, oldValue);
33+
XPath xpath = DocumentHelper.createXPath(expr);
34+
List<Node> nodes = xpath.selectNodes(input);
35+
// 3- Make the change on the selected nodes
36+
for (int i = 0; i < nodes.size(); i++) {
37+
Element element = (Element) nodes.get(i);
38+
element.addAttribute(attribute, newValue);
39+
}
40+
// 4- Save the result to a new XML doc
41+
TransformerFactory factory = TransformerFactory.newInstance();
42+
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
43+
Transformer xformer = factory.newTransformer();
44+
xformer.setOutputProperty(OutputKeys.INDENT, "yes");
45+
Writer output = new StringWriter();
46+
xformer.transform(new DocumentSource(input), new StreamResult(output));
47+
return output.toString();
48+
}
49+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package com.baeldung.xml.attribute;
2+
3+
import org.w3c.dom.Document;
4+
import org.w3c.dom.Element;
5+
import org.w3c.dom.NodeList;
6+
import org.xml.sax.SAXException;
7+
8+
import javax.xml.XMLConstants;
9+
import javax.xml.parsers.DocumentBuilderFactory;
10+
import javax.xml.parsers.ParserConfigurationException;
11+
import javax.xml.transform.*;
12+
import javax.xml.transform.dom.DOMSource;
13+
import javax.xml.transform.stream.StreamResult;
14+
import javax.xml.xpath.XPath;
15+
import javax.xml.xpath.XPathConstants;
16+
import javax.xml.xpath.XPathExpressionException;
17+
import javax.xml.xpath.XPathFactory;
18+
import java.io.IOException;
19+
import java.io.StringWriter;
20+
import java.io.Writer;
21+
22+
public class JaxpTransformer {
23+
24+
private Document input;
25+
26+
public JaxpTransformer(String resourcePath) throws SAXException, IOException, ParserConfigurationException {
27+
// 1- Build the doc from the XML file
28+
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
29+
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
30+
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
31+
this.input = factory.newDocumentBuilder()
32+
.parse(resourcePath);
33+
}
34+
35+
public String modifyAttribute(String attribute, String oldValue, String newValue)
36+
throws XPathExpressionException, TransformerFactoryConfigurationError, TransformerException, TransformerConfigurationException {
37+
// 2- Locate the node(s) with xpath
38+
XPath xpath = XPathFactory.newInstance()
39+
.newXPath();
40+
NodeList nodes = (NodeList) xpath.evaluate(String.format("//*[contains(@%s, '%s')]", attribute, oldValue), this.input, XPathConstants.NODESET);
41+
// 3- Make the change on the selected nodes
42+
for (int i = 0; i < nodes.getLength(); i++) {
43+
Element value = (Element) nodes.item(i);
44+
value.setAttribute(attribute, newValue);
45+
}
46+
// Stream api syntax
47+
// IntStream
48+
// .range(0, nodes.getLength())
49+
// .mapToObj(i -> (Element) nodes.item(i))
50+
// .forEach(value -> value.setAttribute(attribute, newValue));
51+
// 4- Save the result to a new XML doc
52+
TransformerFactory factory = TransformerFactory.newInstance();
53+
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
54+
Transformer xformer = factory.newTransformer();
55+
xformer.setOutputProperty(OutputKeys.INDENT, "yes");
56+
Writer output = new StringWriter();
57+
xformer.transform(new DOMSource(this.input), new StreamResult(output));
58+
return output.toString();
59+
}
60+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package com.baeldung.xml.attribute;
2+
3+
import org.joox.JOOX;
4+
import org.joox.Match;
5+
import org.w3c.dom.Document;
6+
import org.xml.sax.SAXException;
7+
8+
import javax.xml.parsers.DocumentBuilder;
9+
import javax.xml.transform.TransformerFactoryConfigurationError;
10+
import java.io.IOException;
11+
12+
import static org.joox.JOOX.$;
13+
14+
public class JooxTransformer {
15+
16+
private final Document input;
17+
18+
public JooxTransformer(String resourcePath) throws SAXException, IOException {
19+
// 1- Build the doc from the XML file
20+
DocumentBuilder builder = JOOX.builder();
21+
input = builder.parse(resourcePath);
22+
}
23+
24+
public String modifyAttribute(String attribute, String oldValue, String newValue) throws TransformerFactoryConfigurationError {
25+
// 2- Select the document
26+
Match $ = $(input);
27+
// 3 - Find node to modify
28+
String expr = String.format("//*[contains(@%s, '%s')]", attribute, oldValue);
29+
$
30+
// .find("to") or with xpath
31+
.xpath(expr)
32+
.get()
33+
.stream()
34+
.forEach(e -> e.setAttribute(attribute, newValue));
35+
// 4- Return result as String
36+
return $.toString();
37+
}
38+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package com.baeldung.xml.attribute.jmh;
2+
3+
import com.baeldung.xml.attribute.Dom4jTransformer;
4+
import com.baeldung.xml.attribute.JaxpTransformer;
5+
import com.baeldung.xml.attribute.JooxTransformer;
6+
import org.dom4j.DocumentException;
7+
import org.openjdk.jmh.annotations.*;
8+
import org.openjdk.jmh.runner.Runner;
9+
import org.openjdk.jmh.runner.RunnerException;
10+
import org.openjdk.jmh.runner.options.Options;
11+
import org.openjdk.jmh.runner.options.OptionsBuilder;
12+
import org.xml.sax.SAXException;
13+
14+
import javax.xml.parsers.ParserConfigurationException;
15+
import javax.xml.transform.TransformerException;
16+
import javax.xml.xpath.XPathExpressionException;
17+
import java.io.IOException;
18+
import java.util.concurrent.TimeUnit;
19+
20+
@BenchmarkMode(Mode.AverageTime)
21+
@OutputTimeUnit(TimeUnit.MILLISECONDS)
22+
@State(Scope.Benchmark)
23+
public class AttributeBenchMark {
24+
25+
public static void main(String[] args) throws RunnerException {
26+
Options opt = new OptionsBuilder().include(AttributeBenchMark.class.getSimpleName())
27+
.forks(1)
28+
.build();
29+
new Runner(opt).run();
30+
}
31+
32+
@Benchmark
33+
public String dom4jBenchmark() throws DocumentException, TransformerException, SAXException {
34+
String path = this.getClass()
35+
.getResource("/xml/attribute.xml")
36+
.toString();
37+
Dom4jTransformer transformer = new Dom4jTransformer(path);
38+
String attribute = "customer";
39+
String oldValue = "true";
40+
String newValue = "false";
41+
42+
return transformer.modifyAttribute(attribute, oldValue, newValue);
43+
}
44+
45+
@Benchmark
46+
public String jooxBenchmark() throws IOException, SAXException {
47+
String path = this.getClass()
48+
.getResource("/xml/attribute.xml")
49+
.toString();
50+
JooxTransformer transformer = new JooxTransformer(path);
51+
String attribute = "customer";
52+
String oldValue = "true";
53+
String newValue = "false";
54+
55+
return transformer.modifyAttribute(attribute, oldValue, newValue);
56+
}
57+
58+
@Benchmark
59+
public String jaxpBenchmark()
60+
throws TransformerException, ParserConfigurationException, SAXException, IOException, XPathExpressionException {
61+
String path = this.getClass()
62+
.getResource("/xml/attribute.xml")
63+
.toString();
64+
JaxpTransformer transformer = new JaxpTransformer(path);
65+
String attribute = "customer";
66+
String oldValue = "true";
67+
String newValue = "false";
68+
69+
return transformer.modifyAttribute(attribute, oldValue, newValue);
70+
}
71+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Customer.java 06.06.2008
3+
*
4+
* Copyright 2008 Stefan J&auml;ger
5+
*
6+
*/
7+
package com.baeldung.xml.jibx;
8+
9+
import org.apache.commons.lang3.builder.ToStringBuilder;
10+
11+
public class Customer {
12+
private Person person;
13+
private String city;
14+
15+
private Phone homePhone;
16+
private Phone officePhone;
17+
18+
public Person getPerson() {
19+
return person;
20+
}
21+
22+
public void setPerson(Person person) {
23+
this.person = person;
24+
}
25+
26+
public String getCity() {
27+
return city;
28+
}
29+
30+
public void setCity(String city) {
31+
this.city = city;
32+
}
33+
34+
public Phone getHomePhone() {
35+
return homePhone;
36+
}
37+
38+
public void setHomePhone(Phone homePhone) {
39+
this.homePhone = homePhone;
40+
}
41+
42+
public Phone getOfficePhone() {
43+
return officePhone;
44+
}
45+
46+
public void setOfficePhone(Phone officePhone) {
47+
this.officePhone = officePhone;
48+
}
49+
50+
public String toString() {
51+
return ToStringBuilder.reflectionToString(this);
52+
}
53+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.baeldung.xml.jibx;
2+
3+
public class Identity {
4+
5+
long customerId;
6+
7+
public long getCustomerId() {
8+
return customerId;
9+
}
10+
11+
public void setCustomerId(long customerId) {
12+
this.customerId = customerId;
13+
}
14+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Person.java 06.06.2008
3+
*
4+
* Copyright 2008 Stefan J&auml;ger
5+
*
6+
*/
7+
package com.baeldung.xml.jibx;
8+
9+
import org.apache.commons.lang3.builder.ToStringBuilder;
10+
11+
public class Person extends Identity {
12+
private String name;
13+
14+
public String getName() {
15+
return name;
16+
}
17+
18+
public void setName(String name) {
19+
this.name = name;
20+
}
21+
22+
public String toString() {
23+
return ToStringBuilder.reflectionToString(this);
24+
}
25+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.baeldung.xml.jibx;
2+
3+
public class Phone {
4+
5+
private String number;
6+
7+
public String getNumber() {
8+
return number;
9+
}
10+
11+
public void setNumber(String number) {
12+
this.number = number;
13+
}
14+
}

0 commit comments

Comments
 (0)