I have the following XMLfile that i need to parse through and i need to select the firstname of the student whose person_type value=1. I am using dom4j in my java project and i am not able to find a solution to extract the firstname based on the value of the person_type. Any help would be appreciated.
<?xml version="1.0"?>
<class>
<student>
<firstname>dinkar</firstname>
<lastname>kad</lastname>
<nickname>dinkar</nickname>
<marks>85</marks>
<person_types>
<person_type>1</person_type>
<person_description>POC</person_description>
</person_types>
</student>
<student>
<firstname>Vaneet</firstname>
<lastname>Gupta</lastname>
<nickname>vinni</nickname>
<marks>95</marks>
<person_types>
<person_type>1</person_type>
<person_description>Assistant</person_description>
</person_types>
</student>
<student>
<firstname>jasvir</firstname>
<lastname>singn</lastname>
<nickname>jazz</nickname>
<marks>90</marks>
<person_types>
<person_type>1</person_type>`
<person_description>Leader</person_description>
</person_types>
</student>
</class>
public static void main(String[] args) {
try {
File inputFile = new File("input.txt");
SAXReader reader = new SAXReader();
Document document = reader.read( inputFile );
System.out.println("Root element :"
+ document.getRootElement().getName());
Element classElement = document.getRootElement();
List<Node> nodes = document.selectNodes("/class/student" );
System.out.println("----------------------------");
for (Node node : nodes) {
if("1".equals(node.selectSingleNode("person_types").selectSingleNode("person_type").getText())){
System.out.println("\nCurrent Element :"
+ node.getName());
System.out.println("Student roll no : "
+ node.valueOf("#rollno") );
System.out.println("First Name : " + node.selectSingleNode("firstname").getText());
System.out.println("Last Name : " + node.selectSingleNode("lastname").getText());
System.out.println("First Name : " + node.selectSingleNode("nickname").getText());
System.out.println("Marks : " + node.selectSingleNode("marks").getText());
}
}
} catch (DocumentException e) {
e.printStackTrace();
}
}
Related
Given an XML content like below.
Is there an API that can return the whole student node when I pass just the value of rollno. For e.g., If I pass 493 then I should get the student info for 493 with all child elements like firstname, lastname,.. marks etc
<?xml version = "1.0"?>
<class>
<old>
<student rollno = "393">
<firstname>dinkar</firstname>
<lastname>kad</lastname>
<nickname>dinkar</nickname>
<marks>85</marks>
</student>
<student rollno = "493">
<firstname>Vaneet</firstname>
<lastname>Gupta</lastname>
<nickname>vinni</nickname>
<marks>95</marks>
</student>
</old>
<current>
<student rollno = "593">
<firstname>jasvir</firstname>
<lastname>singn</lastname>
<nickname>jazz</nickname>
<marks>90</marks>
</student>
<student rollno = "125">
<firstname>abcd</firstname>
<lastname>defc</lastname>
<nickname>dumy</nickname>
<marks>90</marks>
</student>
<student rollno = "965">
<firstname>xyz</firstname>
<lastname>defc</lastname>
<nickname>sample</nickname>
<marks>90</marks>
</student>
</current>
</class>
Not sure about getting the whole set with one call, but you can get the value for each tag...something like:
File fXmlFile = new File("student.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
doc.getDocumentElement().normalize();
NodeList nList = doc.getElementsByTagName("student");
for (int temp = 0; temp < nList.getLength(); temp++) {
Node nNode = nList.item(temp);
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
System.out.println("Student rollno : "
+ eElement.getAttribute("rollno"));
System.out.println("Firstname : "
+ eElement.getElementsByTagName("firstname")
.item(0).getTextContent());
System.out.println("Last Name : "
+ eElement.getElementsByTagName("lastname")
.item(0).getTextContent());
System.out.println("Nickname : "
+ eElement.getElementsByTagName("nickname")
.item(0).getTextContent());
System.out.println("Marks : "
+ eElement.getElementsByTagName("marks")
.item(0).getTextContent());
}
}
How do I parse complex XML file using DOM ? I need to access each child of grade but I am getting all the classes within xml files.How do I access grade , child , student and teacher elements .
public SchoolM readFileNBuildModel(String filePath) {
File file = new File(filePath);
if (file.exists()) {
AppLauncher.getLog().log(Level.INFO, " File Exist : " + filePath,filePath);
try {
AppLauncher.getLog().log(Level.INFO, " Parsing File : " + filePath,filePath);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder;
documentBuilder = dbf.newDocumentBuilder();
Document doc = documentBuilder.parse(file);
doc.getDocumentElement().normalize();
Element schoolNode = doc.getDocumentElement();
NodeList gradeList = doc.getElementsByTagName("grade");
SortedSet<GradeM> gradeSet = new TreeSet<GradeM>();
for (int temp = 0; temp < gradeList.getLength(); temp++) {
Node gradeNode = gradeList.item(temp);
Element gradeElemet = (Element) gradeNode;
GradeM gradeM = new GradeM(gradeElemet.getAttribute("id"));
SortedSet<ClassM> classSet = new TreeSet<ClassM>();
NodeList classList = doc.getElementsByTagName("classroom");
for (int classIndex = 0; classIndex < classList.getLength(); classIndex++) {
Node classNode = classList.item(classIndex);
Element classElement = (Element) classNode;
ClassM classM = new ClassM(classElement.getAttribute(CSVColumnAttributeEnum.CLASSROOM_ID.getXmlMapColumnName()),
classElement.getAttribute(CSVColumnAttributeEnum.CLASSROOM_NAME.getXmlMapColumnName()));
SortedSet<TeacherM> teacherSet = new TreeSet<TeacherM>();
SortedSet<StudentM> studentSet = new TreeSet<StudentM>();
NodeList teacherList = doc.getElementsByTagName("teacher");
NodeList studentList = doc.getElementsByTagName("student");
for (int studentIndex = 0; studentIndex < studentList.getLength(); studentIndex++) {
Node studentNode = studentList.item(studentIndex);
Element studentElement = (Element) studentNode;
if(studentElement != null){
StudentM studentM = new StudentM(studentElement.getAttribute(CSVColumnAttributeEnum.STUDENT_ID.getXmlMapColumnName()),
studentElement.getAttribute(CSVColumnAttributeEnum.STUDENT_FIRST_NAME.getXmlMapColumnName()), studentElement.getAttribute(CSVColumnAttributeEnum.STUDENT_LAST_NAME.getXmlMapColumnName()),
studentElement.getAttribute(CSVColumnAttributeEnum.STUDENT_GRADE.getXmlMapColumnName()));
studentSet.add(studentM);
}
}
for (int teacherIndex = 0; teacherIndex < teacherList.getLength(); teacherIndex++) {
Node teacherNode = teacherList.item(classIndex);
Element teacherElement = (Element) teacherNode;
if(teacherElement != null){
TeacherM teacherM = new TeacherM(teacherElement.getAttribute(CSVColumnAttributeEnum.TEACHER1_ID.getXmlMapColumnName()),
teacherElement.getAttribute(CSVColumnAttributeEnum.TEACHER1_LAST_NAME.getXmlMapColumnName()), teacherElement.getAttribute(CSVColumnAttributeEnum.TEACHER1_FIRST_NAME.getXmlMapColumnName()));
teacherSet.add(teacherM);
}
}
classM.setStudentSet(studentSet);
classM.setTeacherSet(teacherSet);
classSet.add(classM);
}
gradeM.setClassSet(classSet);
gradeSet.add(gradeM);
}
SchoolM schoolM = new SchoolM(schoolNode.getAttribute("id"), schoolNode.getAttribute("schoolName"),gradeSet);
return schoolM;
} catch (ParserConfigurationException e) {
AppLauncher.getLog().log(Level.SEVERE, " File Conversion failed because of : /n" + e.toString());
} catch (SAXException e) {
AppLauncher.getLog().log(Level.SEVERE, " File Conversion failed because of : /n" + e.toString());
} catch (IOException e) {
AppLauncher.getLog().log(Level.SEVERE, " File Conversion failed because of : /n" + e.toString());
}
}else{
AppLauncher.getLog().log(Level.WARNING, " File Does Not Exist : " + filePath,filePath);
}
return new SchoolM();
XML Files:
<grade id="1">
<classroom id="101" name="Mrs. Jones' Math Class">
<teacher id="10100000001" first_name="Barbara" last_name="Jones"/>
<student id="10100000010" first_name="Michael" last_name="Gil"/>
<student id="10100000011" first_name="Kimberly" last_name="Gutierrez"/>
<student id="10100000013" first_name="Toby" last_name="Mercado"/>
<student id="10100000014" first_name="Lizzie" last_name="Garcia"/>
<student id="10100000015" first_name="Alex" last_name="Cruz"/>
</classroom>
<classroom id="102" name="Mr. Smith's PhysEd Class">
<teacher id="10200000001" first_name="Arthur" last_name="Smith"/>
<teacher id="10200000011" first_name="John" last_name="Patterson"/>
<student id="10200000010" first_name="Nathaniel" last_name="Smith"/>
<student id="10200000011" first_name="Brandon" last_name="McCrancy"/>
<student id="10200000012" first_name="Elizabeth" last_name="Marco"/>
<student id="10200000013" first_name="Erica" last_name="Lanni"/>
<student id="10200000014" first_name="Michael" last_name="Flores"/>
<student id="10200000015" first_name="Jasmin" last_name="Hill"/>
<student id="10200000016" first_name="Brittany" last_name="Perez"/>
<student id="10200000017" first_name="William" last_name="Hiram"/>
<student id="10200000018" first_name="Alexis" last_name="Reginald"/>
<student id="10200000019" first_name="Matthew" last_name="Gayle"/>
</classroom>
<classroom id="103" name="Brian's Homeroom">
<teacher id="10300000001" first_name="Brian" last_name="O'Donnell"/>
</classroom>
</grade>
Use the getElementsByTagName method on the element you are processing e.g. use gradeElemet.getElementByTagName("classroom") instead of doc.getElementsByTagName("classroom"). Then inside all of your nested loops continue that approach to call the method on the currently processed element and not on the complete document.
I am attempting to get the text from an xml node. The code seems to recognize the node. This code
String L = "Node Length: " + nList.getLength()+ " Text: " + nList.item(0).toString();
jTextArea1.setText(L);
returns: Node Length: 1 Text: [CompanyName: null]
So it seems like the code is finding the node but not getting the value. Here is the whole code block (this is my first time posting so I hope I formatted this right!). the FOR loop should grab the value but is throwing a NULL Pointer Exception:
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
try{
//Get Document Builder
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
//Build Document
Document xdocument = builder.parse(new File("request.xml"));
xdocument.getDocumentElement().normalize();
NodeList nList = xdocument.getElementsByTagName("CompanyName");
//String L = "Node Length: " + nList.getLength()+ " Text: " + nList.item(0).toString();
//jTextArea1.setText(L);
for (int temp = 0; temp < nList.getLength(); temp++)
{
Node node = nList.item(0);
if (node.getNodeType() == Node.ELEMENT_NODE)
{
Element eElement = (Element) node;
String nodetxt= "Company : " + eElement.getElementsByTagName("CompanyName").item(0).getTextContent() ;
jTextArea1.setText(nodetxt) ;
}
}
} catch (Exception ex) {
java.util.logging.Logger.getLogger(TechKnowPOSGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
}
and here is the XML file:
<?xml version="1.0" encoding="utf-8"?>
<RunReportQueryAction xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<CompanyName>Techknow</CompanyName>
<IntegrationLoginId>cwapitest</IntegrationLoginId>
<IntegrationPassword>cwtest123</IntegrationPassword>
<ReportName>Company</ReportName>
<!-- <Conditions></Conditions> -->
<!-- <Limit>10</Limit> -->
<!-- <Skip></Skip> -->
<!-- <OrderBy></OrderBy> -->
</RunReportQueryAction>
Any help is greatly appreciated.
On this line you get all the CompanyName elements:
NodeList nList = xdocument.getElementsByTagName("CompanyName");
Then you loop through them in your for loop and call this:
eElement.getElementsByTagName("CompanyName")
But that would imply that the CompanyName has nested CompanyName elements, which it does not. Therefore you should use this in your for loop, as the elements you are iterating are already the CompanyName elements:
String nodeTxt = "Company : " + eElement.getTextContent()
I am trying to parse an xml file in java using the DOM parser and its working fine.
The issue i am having is that i get an error if a tag is not consistent. For example I have an xml file as follows
<employee>
<employeeid></employeeid>
<name></name>
<secondname></secondname>
</employee>
<employee>
<employeeid></employeeid>
<name></name>
<secondname></secondname>
</employee>
<employee>
<employeeid></employeeid>
<secondname></secondname>
</employee>
Because the name tag is missing in the last element i get an error but if i put it in it works fine. Is there any way of fixing this?
System.out.println ("Root element of the doc is " +
doc.getDocumentElement().getNodeName());
NodeList listOfCourses = doc.getElementsByTagName("employee");
int totalCourses = listOfCourses.getLength();
System.out.println("Total no of courses : " + totalCourses);
for(int s=0; s<listOfCourses.getLength() ; s++){
Node firstCourseNode = listOfCourses.item(s);
if(firstCourseNode.getNodeType() == Node.ELEMENT_NODE){
Element firstCourseElement = (Element)firstCourseNode;
//-------
NodeList employeeList = firstCourseElement.getElementsByTagName("employeeId");
Element employeeElement = (Element)employeeList.item(0);
NodeList textFNList = employeeElement.getChildNodes();
System.out.println("CourseId : " +
((Node)textFNList.item(0)).getNodeValue().trim());
//-------
NodeList titleList = firstCourseElement.getElementsByTagName("name");
Element titleElement = (Element)titleList.item(0);
NodeList textLNList = titleElement.getChildNodes();
System.out.println("Title : " +
((Node)textLNList.item(0)).getNodeValue().trim());
//----
NodeList descriptionList = firstCourseElement.getElementsByTagName("secondname");
Element ageElement = (Element)descriptionList.item(0);
NodeList textdescrList = ageElement.getChildNodes();
System.out.println("Description : " +
((Node)textdescrList.item(0)).getNodeValue().trim());
I'm looking for ways to read a generic xml file
Here is an example of a normal xml file
<?xml version="1.0"?>
<students>
<student>
<name>John</name>
<grade>B</grade>
<age>12</age>
</student>
<student>
<name>Mary</name>
<grade>A</grade>
<age>11</age>
</student>
<student>
<name>Simon</name>
<grade>A</grade>
<age>18</age>
</student>
</students>
and here is example of a typical xml parser that would read that code and print it out
public class XMLParser {
public void getAllUserNames(String fileName) {
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
File file = new File(fileName);
if (file.exists()) {
Document doc = db.parse(file);
Element docEle = doc.getDocumentElement();
// Print root element of the document
System.out.println("Root element of the document: "
+ docEle.getNodeName());
NodeList studentList = docEle.getElementsByTagName("student");
// Print total student elements in document
System.out
.println("Total students: " + studentList.getLength());
if (studentList != null && studentList.getLength() > 0) {
for (int i = 0; i < studentList.getLength(); i++) {
Node node = studentList.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE) {
System.out
.println("=====================");
Element e = (Element) node;
NodeList nodeList = e.getElementsByTagName("name");
System.out.println("Name: "
+ nodeList.item(0).getChildNodes().item(0)
.getNodeValue());
nodeList = e.getElementsByTagName("grade");
System.out.println("Grade: "
+ nodeList.item(0).getChildNodes().item(0)
.getNodeValue());
nodeList = e.getElementsByTagName("age");
System.out.println("Age: "
+ nodeList.item(0).getChildNodes().item(0)
.getNodeValue());
}
}
} else {
System.exit(1);
}
}
} catch (Exception e) {
System.out.println(e);
}
}
public static void main(String[] args) {
XMLParser parser = new XMLParser();
parser.getAllUserNames("c:\\test.xml");
}
}
This code needs lines like this
NodeList studentList = docEle.getElementsByTagName("student");
NodeList nodeList = e.getElementsByTagName("name");
In order to work correctly.
My questions comes from how would I make that generic. Is there any way where I could read that same XML file without having to get specific elements by tagNames and yet still print it out in a view able format.
In the above example you are using Dom parser. By using Jaxb Context unmarshaller you can convert the xml to java object, then you can achive your task.
You need to have a generic function to handle.
Generic function is as follows:
/* Prints the Node Value */
public void PrintNodeValue(Element element, String tagName, String msg)
{
NodeList nodeList = element.getElementsByTagName(tagName);
System.out.println(msg + nodeList.item(0).getChildNodes().item(0).getNodeValue());
}
Function is called as below:
PrintNodeValue(e, "name", "Name: ");
PrintNodeValue(e, "grade", "Grade: ");