使用用户输入使用java在xml中搜索某个节点

时间:2013-09-03 13:35:23

标签: java xml

我有这个xml代码

我希望能够拥有一个扫描仪或其他要求用户输入的对象,然后使用该输入来匹配某个节点并显示该节点以及其下的其余节点。

例如,我想要选择搜索姓名,地址,电子邮件,电话或群组。如果我选择名称,我希望能够输入名称“tim”,然后使用该输入来查找节点并将其与兄弟节点一起显示,但仅针对该特定联系人。

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<contactInfo>
    <contact>
        <name>tim</name>
        <primary_address>1111 virginia road</primary_address>
        <secondary_address>N/A</secondary_address>
        <primary_email>asdf@gmail.com</primary_email>
        <backup_email1>N/A</backup_email1>
        <backup_email2>N/A</backup_email2>
        <primary_phone>703-111-1111</primary_phone>
        <backup_phone1>N/A</backup_phone1>
        <backup_phone2>N/A</backup_phone2>
        <group1>family</group1>
        <group2>friends</group2>
    </contact>
    <contact>
        <name>john</name>
        <primary_address>1111 pike road</primary_address>
        <secondary_address>N/A</secondary_address>
        <primary_email>john@gmail.com</primary_email>
        <backup_email1>N/A</backup_email1>
        <backup_email2>N/A</backup_email2>
        <primary_phone>222-222-2222</primary_phone>
        <backup_phone1>N/A</backup_phone1>
        <backup_phone2>N/A</backup_phone2>
        <group1>friends</group1>
        <group2>N/A</group2>
    </contact>
    <contact>
        <name>Tim Calara</name>
        <primary_address>1234 Wallaby Way</primary_address>
        <secondary_address>N/A</secondary_address>
        <primary_email>tim@gmail.com</primary_email>
        <backup_email1>N/A</backup_email1>
        <backup_email2>N/A</backup_email2>
        <primary_phone>111-123-4567</primary_phone>
        <backup_phone1>N/A</backup_phone1>
        <backup_phone2>N/A</backup_phone2>
        <group1>family</group1>
        <group2>friends</group2>
    </contact>
   </contactInfo>

这是我的代码的搜索部分,如果您需要我的整个代码,请告诉我(整个过程非常冗长)。

public void search() throws SAXException, IOException, ParserConfigurationException, XPathExpressionException
{
    System.out.println("\nSearch for Contact");
    int choice = searchMenu ( );

    switch (choice)
    {
    case 1: 
        try 
        {

            File file = new File("/Users/T/Eclipse Workspace/contactInfo/nData.xml");
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document xmlDocument = dBuilder.parse(file);
            XPath xPath =  XPathFactory.newInstance().newXPath();

            System.out.println("Please enter Contact name: ");
            String input = kbd.nextLine();

            String expression = "/contactInfo/contact[name() = "input"]";
            System.out.println(expression);
            Node node = (Node) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODE);
            if(null != node) {
               NodeList nodeList = node.getChildNodes();
                for (int i = 0;null!=nodeList && i < nodeList.getLength(); i++) {
                    Node nod = nodeList.item(i);
                    if(nod.getNodeType() == Node.ELEMENT_NODE)
                        System.out.println(nodeList.item(i).getNodeName() + " : " + nod.getFirstChild().getNodeValue()); 
                }
            }


        } 
        catch (Exception e) 
        {
            e.printStackTrace();
        }
        break;

    //case 2:

    //case 3: email ( ); break;
    //case 4: phone ( ); break;
    //case 5: break;            
    //case 6: exit (); break;
        }       
}

3 个答案:

答案 0 :(得分:1)

你试过JAXB吗?

“用于XML绑定的Java体系结构(JAXB)允许Java开发人员将Java类映射到XML表示。”

然后你可以迭代对象。

http://en.wikipedia.org/wiki/Java_Architecture_for_XML_Binding

答案 1 :(得分:0)

以下示例将找到包含内容为name的{​​{1}}子项的第一个元素,并打印其timname元素的内容:

primary_address

这可能不是最干净的方式,但它确实起到了作用。你可以将大部分内容包装在辅助方法中 - 注意两个Document doc = getDocument(); XPath xpath = XPathFactory.newInstance().newXPath(); NodeList nodeList; nodeList = (NodeList) xpath.evaluate("//name[.='tim']/..", doc, XPathConstants.NODESET); for(int i = 0; i < nodeList.getLength(); i++) { Node contact = nodeList.item(i); System.out.println("Name: " + ((Node)xpath.evaluate("name", contact, XPathConstants.NODE)).getTextContent()); System.out.println("Address: " + ((Node)xpath.evaluate("primary_address", contact, XPathConstants.NODE)).getTextContent()); } 语句的相似程度,它们只是为了分解而烦恼。

[EDIT]根据评论中的要求更新了示例

答案 2 :(得分:0)

以下是使用JAXB将XML表示映射到Java类的方法:在给定的XML中,ContactInfo元素包含contact个子元素的列表。如果您将ContactInfoConatct表示为Java对象,ContactInfo将包含Contact个实例的列表。下面是实现此目的的示例代码:

创建Contact类:

@XmlRootElement
public class Contact{
private String name;
private String primaryAddress;
//other properties
// getters and setters
}

这是ContactInfo类,其中包含表示XML文件的联系元素的Contact个对象列表:

@XmlRootElement
public class ContactInfo {
private List<Contact> contactList;

public List<Contact> getContactList() {
    return contactList;
}

    @XmlElementWrapper(name = "ContactList")
    @XmlElement(name = "Contact")
    public void setCustomerList(List<Contact> contactList) {
        this.contactList =contactList;
    }
}

现在,通过使用JAXB,您可以按如下方式读取xml文件:

File file = new File("Path to your xml file");
JAXBContext jaxbContext = JAXBContext.newInstance(ContactInfo.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
ContactInfo contactInfo = (ContactInfo) unmarshaller.unmarshal(file);

您还可以从ContactInfo创建xml,如下所示:

//create your "ContactInfo" object with a list of "Contact"s
ContactInfo contactInfo=new ContactInfo();
List<Contact> list=new ArrayList<>();
//add contacts to the list and add the list to ContactInfo

File file = new File("path to save your XML file");
JAXBContext jaxbContext = JAXBContext.newInstance(ContactInfo.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
jaxbMarshaller.marshal(contactInfo, file);

我建议你阅读:Java Architecture for XML Binding以便对API有所了解。