/********************************************************** * ContactReport accepts a first name and last name * as command-line parameters. The class then parses the AddressBook.xml file, * creating the DOM object (Document) and searches through the DOM for the * entered first name and last name node combination. If they're found, the * program then traverses backward up the node tree and prints out the relevant * content from the nodes that comprise that contact. * * 16-Oct-2004 Works but I don't like the output--not very readable. I also * want to output the info not necessarily in the order that it's input. * * 28-OCT-2004 Updated to use two different methods to process the subnodes. * One method uses the element tags to display some info, the * other method doesn't display the element tag. The order of the output * is deliberately different than the structure of the tree, to make a more * readable report. * * Kelli Wiseth * * * XML and Web Services class | NDNU * *********************************************************** */ // Java core packages import java.io.*; import java.util.regex.*; // Java standard extensions import javax.xml.parsers.*; import javax.xml.transform.*; // third-party libraries import org.w3c.dom.*; import org.w3c.dom.traversal.*; import org.xml.sax.*; public class ContactReport { String findFirstname = ""; String findLastname = ""; String filename = "AddressBook.xml"; String nodeValue = " "; String textToPrint = ""; boolean lastNameExists = false; boolean firstNameExists = false; DocumentBuilder addressBookParser; Document addressBook; Element contact; int nodeType; public ContactReport( String findFirstname, String findLastname ) { // parse XML, create DOM tree, and find the contact try { // obtain default parser DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setValidating( false ); DocumentBuilder addressBookParser = dbf.newDocumentBuilder(); Document addressBook = addressBookParser.parse( new File( filename ) ); addressBook.getDocumentElement().normalize(); String firstnameLookup = findFirstname; String lastnameLookup = findLastname; String spouseName = ""; NodeList contactsAll = addressBook.getElementsByTagName("Contact"); NodeList namesAll = addressBook.getElementsByTagName("Name"); for (int ctr1 = 0; ctr1 < contactsAll.getLength(); ctr1++) { /*Setup the Nodes in the DOM that we need to get to in order to find the * last name element and subsequently, the first name element. Cast to * Element as required in to obtain Element tag names and create NodeLists * within our found object that comprise the nodes of interest */ Node contactName = namesAll.item(ctr1); Element names = (Element)namesAll.item(ctr1); NodeList lastNameList = names.getElementsByTagName("Last"); Node lastNameElement = lastNameList.item(0); Node lastNameTextNode = lastNameElement.getFirstChild(); String lastNameText = lastNameTextNode.getNodeValue().trim(); NodeList firstNameList = names.getElementsByTagName("First"); Element firstNameElement = (Element)firstNameList.item(0); Node firstNameTextNode = firstNameElement.getFirstChild(); String firstNameText = firstNameTextNode.getNodeValue().trim(); if ( lastNameText.equalsIgnoreCase(lastnameLookup) ) { lastNameExists=true; if ( firstNameText.equalsIgnoreCase( firstnameLookup ) ) { firstNameExists=true; Node foundContactName = contactName; String foundNickname = names.getAttribute("Nickname"); Node foundPrimaryInfo = foundContactName.getParentNode(); Node foundContactRootNode = foundPrimaryInfo.getParentNode(); Node foundPersonalInfo = foundContactRootNode.getNextSibling(); Element contactSpecsSubDoc = (Element)foundContactRootNode; NodeList contactHomeAddress = contactSpecsSubDoc.getElementsByTagName("HomeAddress"); NodeList contactEmail = contactSpecsSubDoc.getElementsByTagName("Email"); NodeList contactPhones = contactSpecsSubDoc.getElementsByTagName("Phones"); NodeList contactWebsitePers = contactSpecsSubDoc.getElementsByTagName("Website"); NodeList contactWorkAddress = contactSpecsSubDoc.getElementsByTagName("WorkAddress"); NodeList contactWorkPhones = contactSpecsSubDoc.getElementsByTagName("WorkPhones"); NodeList contactWebsiteWork = contactSpecsSubDoc.getElementsByTagName("WorkWebsite"); NodeList contactDates = contactSpecsSubDoc.getElementsByTagName("Dates"); NodeList contactNotes = contactSpecsSubDoc.getElementsByTagName("Notes"); NodeList contactSpouse = contactSpecsSubDoc.getElementsByTagName("Spouse"); NodeList contactChildren = contactSpecsSubDoc.getElementsByTagName("Children"); NodeList contactcNames = contactSpecsSubDoc.getElementsByTagName("cName"); /* Search through all the nodes of our foundContact node and then call the * method to iterate through that sub-structure and print out what we want. * In some cases, we call the method to print the element tags as well, but * in many cases, I don't want to see the element tags. */ if (foundNickname.equals("")) { System.out.println("\n\tContact report from address book for " + firstNameText + " " + lastNameText + ":"); } else { System.out.println("\n\tContact report from address book for " + firstNameText + " " + lastNameText + ", aka \"" + foundNickname + "\" :"); } if (contactHomeAddress.getLength() > 0) { System.out.print("\n\tPersonal address and phone lines: \n" ); for (int a = 0; a < contactHomeAddress.getLength(); a++) { Element homeAddress = (Element)contactHomeAddress.item(a); System.out.println("\t"+ getNodeTextNoElements(homeAddress)); } } if (contactPhones.getLength() > 0) { for (int p = 0; p < contactPhones.getLength(); p++) { Node homePhones = contactPhones.item(p); System.out.println("\t"+ getNodeTextWithElements(homePhones)); } } if (contactDates.getLength() > 0) { System.out.print("\n\tDates to remember: \n"); for (int d = 0; d < contactDates.getLength(); d++) { Node dates = contactDates.item(d); System.out.println("\t" + getNodeTextWithElements(dates)); } } if (contactSpouse.getLength() > 0) { System.out.print("\n\tSpouse's name and birthday: "); for (int s = 0; s < contactSpouse.getLength(); s++) { Element spouse = (Element)contactSpouse.item(s); String spousesBirthday = spouse.getAttribute("sBirthday"); spouseName += getNodeTextNoElements(spouse); System.out.print(spouseName + " " + spousesBirthday); } } if (contactChildren.getLength() > 0) { System.out.print("\n\t" + foundNickname + " and" + spouseName + "have " + contactChildren.getLength() + " children:\n"); for (int y = 0; y < contactChildren.getLength(); y++) { // in this loop get each Children node element Element offspringChild = (Element)contactChildren.item(y); Element cNameElement = (Element)contactcNames.item(y); Node cNameNode = contactcNames.item(y); NodeList cFirstNameList = cNameElement.getElementsByTagName("First"); NodeList cLastNameList = cNameElement.getElementsByTagName("Last"); Element cFirstName = (Element)cFirstNameList.item(0); Element cLastName = (Element)cLastNameList.item(0); String cFirstNameText = cFirstName.getNodeValue(); String cLastNameText = cLastName.getNodeValue(); String childsBirthday = offspringChild.getAttribute("cBirthday"); System.out.println("\t" + getNodeTextNoElements(cNameNode) + " " + "\t[Born " + childsBirthday + "]"); } } System.out.println("\n\n\tBusiness address and phones: "); if (contactWorkAddress.getLength() >0) { for (int w = 0; w < contactWorkAddress.getLength(); w++) { Node workAddress = contactWorkAddress.item(w); System.out.println("\t"+ getNodeTextNoElements(workAddress)); } } if (contactWorkPhones.getLength() > 0) { for (int wP = 0; wP < contactWorkPhones.getLength(); wP++) { Node workPhones = contactWorkPhones.item(wP); System.out.println("\t"+ getNodeTextWithElements(workPhones)); } } if (contactEmail.getLength() > 0) { System.out.print("\n\tInternet points of contact:"); Element emailAddresses = (Element)contactEmail.item(0); String alternateEmail = emailAddresses.getAttribute("AlternativeEmail"); NodeList workOrHome = emailAddresses.getChildNodes(); if (workOrHome.getLength() > 0) { System.out.print("\n\tPrimary email address:"); for (int e = 0; e < workOrHome.getLength(); e++) { Node mainEmail = workOrHome.item(e); System.out.print(getNodeTextNoElements(mainEmail)); } } if (alternateEmail==""); else System.out.print("\n\tAlternate email: " + alternateEmail); } if (contactWebsitePers.getLength() > 0) { System.out.print("\n\tPersonal website: " ); for (int b = 0; b < contactWebsitePers.getLength(); b++) { Node contactWebsite1 = contactWebsitePers.item(b); System.out.print(getNodeTextNoElements(contactWebsite1)); } } if (contactWebsiteWork.getLength() > 0) { System.out.print("\n\tBusiness website: "); for (int ws = 0; ws < contactWebsiteWork.getLength(); ws++) { Node contactWebsite2 = contactWebsiteWork.item(ws); System.out.print(getNodeTextNoElements(contactWebsite2)); } } if (contactNotes.getLength() > 0) { System.out.print("\n\n\tNotes:\n"); for (int d = 0; d < contactNotes.getLength(); d++) { Node notes = contactNotes.item(d); System.out.println("\t" + getNodeTextNoElements(notes)); } } else { System.out.print("\n\n\tNo other information about " + firstNameText + " " + lastNameText + " in the AddressBook. \n"); } } // if firstNameText equals firstnameLookup } // if lastName.equals lastnameLookup } //for-loop ctr1 if ((!lastNameExists) || (lastNameExists) && (!firstNameExists)) System.out.println("Contact named " + findFirstname + " " + findLastname + " not found in the address book \nor is not a primary contact."); } //close try block /* The parser exceptions aren't needed, since we're not creating a * DOM structure except by passing in a pre-validated XML file, and * we've turned off validation. However, the IOException will be raised * when there are problems with the XML filename being passed. */ // handle exception thrown by DocumentBuilder catch ( ParserConfigurationException parserException ) { parserException.printStackTrace(); } // handle exception thrown by Parser catch ( SAXException saxException ) { saxException.printStackTrace(); } // handle exception thrown when reading data from file catch ( IOException ioException ) { System.out.print("Syntax: java ContactReport \n"); System.out.print("Please enter contact's first name and last name, as in: \n\n"); System.out.print(" java ContactReport marie sklodowska \n"); System.exit( 1 ); } } //close constructor public String getNodeTextNoElements(Node node) { String textToPrint = ""; if (node.hasChildNodes()) { NodeList children = node.getChildNodes(); for (int i =0; i < children.getLength(); i++) { Node child = children.item(i); child.normalize(); int nodeType = child.getNodeType(); if (nodeType == Node.TEXT_NODE) if((child.getNodeValue()==null) || (child.getNodeValue().equals("\t")) || (child.getNodeValue().trim().equals("\n"))) { //do nothing textToPrint += ""; } else { textToPrint += child.getNodeValue().trim() + " "; } textToPrint += getNodeTextNoElements(child); } //close for loop } // close topmost if return textToPrint; } // close getNodeTextNoElements method public String getNodeTextWithElements(Node node) { String textToPrint = ""; if (node.hasChildNodes()) { NodeList children = node.getChildNodes(); for (int i = 0; i < children.getLength(); i++) { Node child = children.item(i); child.normalize(); int nodeType = child.getNodeType(); if (nodeType == Node.ELEMENT_NODE) { textToPrint += child.getNodeName().trim() + ": "; } if (nodeType == Node.TEXT_NODE) if((child.getNodeValue()==null) || (child.getNodeValue().equals("\t")) || (child.getNodeValue().trim().equals("\n"))) { //do nothing textToPrint += ""; } else { textToPrint += child.getNodeValue().trim() + " "; } textToPrint += getNodeTextWithElements(child); } //close for loop } // close topmost if return textToPrint; } // close getNodeTextwithElements method public static void main( String args[] ) { if ( args.length < 2 ) { System.out.print("Syntax: java ContactReport \n"); System.out.print("Please enter contact's first name and last name, as in: \n\n"); System.out.print(" java ContactReport marie sklodowska \n"); System.exit( 1 ); } ContactReport report = new ContactReport( args[0], args[1] ); }//close main method } //close class ContactReport