I know to convert the XML File to an object we need to create the object first and then convert the XML file to this fixed object. Is there any possibility to have a method to convert any XML file to a Java object which is not fixed and defined before? Or maybe is there any possibility to first of all read and get the headers and nodes in the XML file and then automatically write an object? So, can I create an object from any file automatically?
Later I want to use the object to analyse the content.
Imagine we are talking about a method that can convert both following XML data to a Java object:
<?xml version="1.0" encoding="UTF-8"?>
<breakfast_menu>
<food>
<name>Belgian Waffles</name>
<price>$5.95</price>
<description>
Two of our famous Belgian Waffles with plenty of real maple syrup
</description>
<calories>650</calories>
</food>
<food>
<name>Strawberry Belgian Waffles</name>
<price>$7.95</price>
<description>
Light Belgian waffles covered with strawberries and whipped cream
</description>
<calories>900</calories>
</food>
<food>
<name>Berry-Berry Belgian Waffles</name>
<price>$8.95</price>
<description>
Belgian waffles covered with assorted fresh berries and whipped cream
</description>
<calories>900</calories>
</food>
<food>
<name>French Toast</name>
<price>$4.50</price>
<description>
Thick slices made from our homemade sourdough bread
</description>
<calories>600</calories>
</food>
<food>
<name>Homestyle Breakfast</name>
<price>$6.95</price>
<description>
Two eggs, bacon or sausage, toast, and our ever-popular hash browns
</description>
<calories>950</calories>
</food>
</breakfast_menu>
<?xml version="1.0"?>
<?xml-stylesheet href="catalog.xsl" type="text/xsl"?>
<!DOCTYPE catalog SYSTEM "catalog.dtd">
<catalog>
<product description="Cardigan Sweater" product_image="cardigan.jpg">
<catalog_item gender="Men's">
<item_number>QWZ5671</item_number>
<price>39.95</price>
<size description="Medium">
<color_swatch image="red_cardigan.jpg">Red</color_swatch>
<color_swatch image="burgundy_cardigan.jpg">Burgundy</color_swatch>
</size>
<size description="Large">
<color_swatch image="red_cardigan.jpg">Red</color_swatch>
<color_swatch image="burgundy_cardigan.jpg">Burgundy</color_swatch>
</size>
</catalog_item>
<catalog_item gender="Women's">
<item_number>RRX9856</item_number>
<price>42.50</price>
<size description="Small">
<color_swatch image="red_cardigan.jpg">Red</color_swatch>
<color_swatch image="navy_cardigan.jpg">Navy</color_swatch>
<color_swatch image="burgundy_cardigan.jpg">Burgundy</color_swatch>
</size>
<size description="Medium">
<color_swatch image="red_cardigan.jpg">Red</color_swatch>
<color_swatch image="navy_cardigan.jpg">Navy</color_swatch>
<color_swatch image="burgundy_cardigan.jpg">Burgundy</color_swatch>
<color_swatch image="black_cardigan.jpg">Black</color_swatch>
</size>
<size description="Large">
<color_swatch image="navy_cardigan.jpg">Navy</color_swatch>
<color_swatch image="black_cardigan.jpg">Black</color_swatch>
</size>
<size description="Extra Large">
<color_swatch image="burgundy_cardigan.jpg">Burgundy</color_swatch>
<color_swatch image="black_cardigan.jpg">Black</color_swatch>
</size>
</catalog_item>
</product>
</catalog>
CodePudding user response:
You can use Jackson library jackson-dataformat-xml for that.
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.13.1</version>
</dependency>
Example:
public static void main(String[] args) throws JsonProcessingException {
XmlMapper objectMapper = new XmlMapper();
Object readValue = objectMapper.readValue("<A><id>1</id><name>Jeff</name> <id>2</id><name>John</name> </A>",
Object.class);
LinkedHashMap x = (LinkedHashMap) readValue;
x.entrySet().stream()
.forEach(x1 -> System.out.println(ReflectionToStringBuilder.toString(x1, ToStringStyle.JSON_STYLE)));
}
Result:
{"after":"name=[Jeff, John]","before":null,"hash":3355,"key":"id","next":null,"value":["1","2"]} {"after":null,"before":"id=[1, 2]","hash":3373752,"key":"name","next":null,"value":["Jeff","John"]}
CodePudding user response:
If you want to save or display the result of parsing, I suggest as below.
public class Parsing {
private static String XML_PATH = "";
public static void main(String[] args) {
List<Xml> list = new ArrayList<Xml>();
try {
// read
File xml = new File(XML_PATH);
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
dbFactory.setAttribute("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document document = dBuilder.parse(xml);
document.getDocumentElement().normalize();
// parse
parse(list, document.getDocumentElement(), "/");
} catch (Exception e) {
e.printStackTrace();
}
for (Xml xml : list) {
System.out.println("nodeName: " xml.getNodeName());
System.out.println("xPath: " xml.getxPath());
if (xml.getContents() != null) {
System.out.println("contents: " xml.getContents());
}
System.out.println();
}
}
private static void parse(List<Xml> list, Node node, String xpath) {
if (node.getNodeType() == Node.ELEMENT_NODE) {
list.add(new Xml(node.getNodeName(), xpath, null));
NodeList childNode = node.getChildNodes();
for (int i = 0; i < childNode.getLength(); i ) {
Node n = childNode.item(i);
parse(list, n, xpath node.getNodeName() "/");
}
} else if (node.getNodeType() == Node.TEXT_NODE && !node.getTextContent().trim().isEmpty()) {
list.add(new Xml(node.getParentNode().getNodeName(), xpath, node.getTextContent().trim()));
}
}
}
class Xml {
private String nodeName;
private String xPath;
private String contents;
public Xml(String nodeName, String xPath, String contents) {
this.nodeName = nodeName;
this.xPath = xPath;
this.contents = contents;
}
public String getNodeName() {
return nodeName;
}
public String getxPath() {
return xPath;
}
public String getContents() {
return contents;
}
}