Reputation: 109
I have some xml records as below
<records>
<record>
<name>SK</name>
<age>30</age>
</record>
<record>
<name>KK</name>
<age>10</age>
</record>
<record>
<name>RK</name>
<age>50</age>
</record>
<record>
<name>KB</name>
<age>15</age>
</record>
</records>
I use SAX Parser to validate records and eliminate age <20. So now I want to copy records to another xml file
<records>
<record>
<name>SK</name>
<age>30</age>
</record>
<record>
<name>RK</name>
<age>50</age>
</record>
</records>
I used recursive parsing to extract the tags and values and validate for records having age>20. However I am stuck up with how to take only the record with age > 20 an copy it to another file.
Could anyone please help on this?
Java code as below
// extracts the tags from the xml ile
private static void visit(Node node, int level) {
NodeList list = node.getChildNodes();
String nodeName = new String();
String nodeValue = new String();
// System.out.println(list);
for (int i = 0; i < list.getLength(); i++) {
Node childNode = list.item(i);
if (childNode.getNodeType() == Node.ELEMENT_NODE) {
nodeName = childNode.getNodeName().toString();
System.out.println(nodeName);
if (PROPERTY_AGE.equals(nodeName)) {
nodeValue = childNode.getTextContent();
System.out.println(nodeName + " : " + nodeValue.trim());
int age = Integer.parseInt(nodeValue.trim());
if(age>20) {
/*
Here I would need to copy the current xml between <record></record> to another xml file.
How can the entire record be extracted using Java?
*/
}
}
visit(childNode, level + 1);
}
}
}
private static void readXMLFileAnddisplayTags(File inputXMLFile) {
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
DefaultHandler handler = new DefaultHandler();
InputStream inputStream = new FileInputStream(inputXMLFile);
InputSource is = new InputSource(new InputStreamReader(inputStream, "UTF-8"));
is.setEncoding("UTF-8");
Document document = builder.parse(is);
visit(document, 0);
} catch (ParserConfigurationException | SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Upvotes: 0
Views: 374
Reputation: 5173
Using Jackson-XML-Mapper, the NIO-API and the Stream-API you can achieve your goal with few lines of code.
public static void main(String[] args) throws Exception {
JacksonXmlModule module = new JacksonXmlModule();
module.setDefaultUseWrapper(false);
XmlMapper xmlMapper = new XmlMapper(module);
Records input = xmlMapper.readValue(Files.newInputStream(Paths.get("./records.xml")), Records.class);
List<Record> above20 = input.getRecord().stream()
.filter(r -> r.getAge() > 20)
.collect(Collectors.toList());
Records output = new Records();
output.setRecord(above20);
String xml = xmlMapper.writeValueAsString(output);
Files.write(Paths.get("./records2.xml"), xml.getBytes(StandardCharsets.UTF_8));
}
All you need is to define two classes for the both XML elements:
class Records {
private List<Record> record;
public List<Record> getRecord() {
return record;
}
public void setRecord(List<Record> record) {
this.record = record;
}
}
class Record {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
Upvotes: 1